How do you group first and then apply filtering using Java streams?
Example: Consider this Employee class:
I want to group by Departme
Use Map#putIfAbsent(K,V) to fill in the gaps after filtering
Map> map = list.stream()
.filter(e->e.getSalary() > 2000)
.collect(Collectors.groupingBy(Employee::getDepartment, HashMap::new, toList()));
list.forEach(e->map.putIfAbsent(e.getDepartment(), Collections.emptyList()));
Note: Since the map returned by groupingBy is not guaranteed to be mutable, you need to specify a Map Supplier to be sure (thanks to shmosel for pointing that out).
Another (not recommended) solution is using toMap instead of groupingBy, which has the downside of creating a temporary list for every Employee. Also it looks a bit messy
Predicate filter = e -> e.salary > 2000;
Map> collect = list.stream().collect(
Collectors.toMap(
e-> e.department,
e-> new ArrayList(filter.test(e) ? Collections.singleton(e) : Collections.emptyList()) ,
(l1, l2)-> {l1.addAll(l2); return l1;}
)
);