Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

245
Visualizações
¿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?

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

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());
about 4 years ago · Santiago Trujillo Relatório

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".

about 4 years ago · Santiago Trujillo Relatório

0

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

 details.stream().filter(detail-> detail.getItem()==item && detail.getName()==name && ...)
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda