Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

253
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!