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 Predicate
s.
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.