Apply multiple filter to a map in Java

Nakrule :

Based on the following question: filter Map in Java 8 Streams

public void filterStudents(Map<Integer, Student> studentsMap){
    Map<Integer, Student> filteredStudentsMap = 
        studentsMap.entrySet()
                   .stream()
                   .filter(s -> s.getValue().getAddress().equalsIgnoreCase("delhi"))
                   .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

This filter students leaving in dehli. How could I filter students leaving in dehli, amsterdam or new york?

Is there a better way than filtering three times the original map and merging the three outputs together?

Andrew Tobilko :

There is Predicate#or(Predicate) to logically compose two Predicates.

Predicate<Student> livesInDelhi = student -> "delhi".equalsIgnoreCase(student.getAddress());
Predicate<Student> livesInAmsterdam = student -> "amsterdam".equalsIgnoreCase(student.getAddress());
Predicate<Student> livesInNewYork = student -> "new york".equalsIgnoreCase(student.getAddress());

Predicate<Student> livesInAnyOfTheseThreeCities = livesInDelhi.or(livesInAmsterdam).or(livesInNewYork);

A filter call would look like

.filter(e -> livesInAnyOfTheseThreeCities.test(e.getValue()))

How could I adapt the fourth lines where you're chaining filtering parameters?

Assuming we have an array of cities

final String[] cities = {"delhi", "amsterdam", "new york"};

for each Student, we could write a Predicate<Student> and reduce them by Predicate::or

Predicate<Student> livesInAnyOfGivenCities = 
  Arrays.stream(cities)
    .map(city -> (Predicate<Student>) student -> city.equalsIgnoreCase(student.getAddress()))
    .reduce(Predicate::or)
    .orElseGet(() -> student -> false);

student -> false is used when there are no cities given.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=164731&siteId=1