Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

248
Vistas
¿Cuál es la mejor manera de filtrar por múltiples campos en Java?

Tengo una entidad con 10 campos:

 Class Details{ String item; String name; String type; String origin; String color; String quality; String country; String quantity; Boolean availability; String price; }

Tengo un punto final tranquilo que sirve una Lista. Quiero que el usuario pueda proporcionar filtros de búsqueda para cada campo. Actualmente tengo QueryParam para cada campo. Luego filtro usando java8 stream:

 List<Detail> details; details.stream().filter(detail-> detail.getItem()==item).filter(detail-> detail.getName()==name).....collect(Collectors.toList());

Si tengo otras 50 clases con múltiples campos que quiero filtrar, ¿hay alguna forma de generalizar esto?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Puede componer dichos predicados con .and() y .or() , lo que le permite definir un único predicado agregado que aplica todas las comprobaciones que desea, en lugar de intentar encadenar n llamadas .filter() . Esto permite predicados arbitrariamente complejos que se pueden construir en tiempo de ejecución.

 // Note that you shouldn't normally use == on objects Predicate<Detail> itemPredicate = d-> item.equals(d.getItem()); Predicate<Detail> namePredicate = d-> name.equals(d.getName()); details.stream() .filter(itemPredicate.and(namePredicate)) .collect(Collectors.toList());
over 4 years ago · Santiago Trujillo Denunciar

0

Si quieres evitar la reflexión ¿qué tal algo así?

 static enum DetailQueryParams { ITEM("item", d -> d.item), NAME("name", d -> d.name), TYPE("type", d -> d.type), ORIGIN("origin", d -> d.origin), COLOR("color", d -> d.color), QUALITY("quality", d -> d.quality), COUNTRY("country", d -> d.country), QUANTITY("quantity", d -> d.quantity), AVAILABILITY("availability", d -> d.availability), PRICE("price", d -> d.price); private String name; private Function<Detail, Object> valueExtractor; private DetailQueryParams(String name, Function<Detail, Object> valueExtractor) { this.name = name; this.valueExtractor = valueExtractor; } public static Predicate<Detail> mustMatchDetailValues( Function<String, Optional<String>> queryParamGetter) { return Arrays.asList(values()).stream() .map(p -> queryParamGetter.apply(p.name) .map(q -> (Predicate<Detail>) d -> String.valueOf(p.valueExtractor.apply(d)).equals(q)) .orElse(d -> true)) .reduce(Predicate::and) .orElse(d -> true); } }

Y luego, suponiendo que puede acceder a los parámetros de consulta, por ejemplo request.getQueryParam(String name) que devuelve un valor de String o null , use el código llamando a lo siguiente:

 details.stream() .filter(DetailQueryParams.mustMatchDetailValues( name -> Optional.ofNullable(request.getQueryParam(name)))) .collect(Collectors.toList());

Lo que el método básicamente hace es:

 - for each possible query param - get its value from the request - if value is present build predicate which - gets field value from detail object and convert to string - check that both strings (queried and extracted) matches - if value is not present return predicate that always returns true - combine resulting predicates using and - use always true as fallback (which here never actually happens)

Por supuesto, esto también podría extenderse para generar predicados dependiendo del tipo de valor real en lugar de comparar cadenas para que, por ejemplo, los rangos puedan solicitarse y manejarse a través de "priceMin" y/o "priceMax".

over 4 years ago · Santiago Trujillo Denunciar

0

Para detalles de Lambda -> condición. Entonces podemos especificar cuántos se requieren.

 details.stream().filter(detail-> detail.getItem()==item && detail.getName()==name && ...)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda