How to apply Filtering on groupBy in java streams

后端 未结 5 852
孤城傲影
孤城傲影 2020-12-05 10:16

How do you group first and then apply filtering using Java streams?

Example: Consider this Employee class: I want to group by Departme

5条回答
  •  暖寄归人
    2020-12-05 10:27

    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;}
            )
    );
    

提交回复
热议问题