Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Stream filter match multiple criteria predicate

Given a list of Person:

class Person {
  private Integer id;
  private Integer age;
  private String name;
  private Long lat;
  private Long lont;
  private Boolean hasComputer;
...

I'd like to return the top 5 persons given a set of Criterias such as Age between 30 and 32, that have a computer.

I'd like to try to match all the criterias first but if it doesn't work, try to match any of these.

I have in mind a similar way to do it such as a fulltextsearch would do with a ranking system? But I'm new to Stream so still looking for solution on how to do it.

List<Person> persons = service.getListPersons();
persons.stream().filter(p -> p.getAge.equals(age) && p.hasComputer().equals(true)).allMatch()

Any idea? Thanks!

  • EDIT: Maybe I could create a predicate such as

    Predicate predicate = p -> p.getAge() < 30 && e.name.startsWith("A");

and try first to match all the criteria and if not possible, try to match any:

Persons.steam().allMatch(predicate).limit(5);
Person.steam().anyMatch(predicate).limit(5);
like image 872
Andrew Avatar asked Sep 13 '25 00:09

Andrew


1 Answers

Try this out,

List<Person> filteredPeople = persons.stream()
    .filter(p -> p.getAge() > 30)
    .filter(p -> p.getAge() < 32)
    .filter(p -> p.getHasComputer())
    .limit(5).collect(Collectors.toList());

Notice that you may add additional filter predicates as needed. This is just a template to get your work done.

Or else if you have some dynamic number of Predicates passed by some external client you can still do it like so.

Predicate<Person> ageLowerBoundPredicate = p -> p.getAge() > 30;
Predicate<Person> ageUpperBoundPredicate = p -> p.getAge() < 32;
Predicate<Person> hasComputerPred = p -> p.getHasComputer();
List<Predicate<Person>> predicates = Arrays.asList(ageLowerBoundPredicate, ageUpperBoundPredicate,
                hasComputerPred);
List<Person> filteredPeople = persons.stream()
        .filter(p -> predicates.stream().allMatch(f -> f.test(p)))
        .limit(5).collect(Collectors.toList());
like image 52
Ravindra Ranwala Avatar answered Sep 14 '25 19:09

Ravindra Ranwala