Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Filter Map<String,List<Employee>>

How to filter a Map<String, List<Employee>> using Java 8 Filter?

I have to filter only when any of employee in the list having a field value Gender = "M".

Input: Map<String,List<Employee>>
Output: Map<String,List<Employee>>
Filter criteria: Employee.genter = "M"

Also i have to filter out the key in the output map (or filter map [new map we get after filter]) if the List<> is empty on the map value

like image 877
Ranji Avatar asked Aug 01 '18 09:08

Ranji


2 Answers

To filter out entries where a list contains an employee who is not of the "M" gender:

Map<String, List<Employee>> r2 = map.entrySet().stream()
    .filter(i -> i.getValue().stream().allMatch(e-> "M".equals(e.gender)))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

To filter out employees who are not of the "M" gender:

Map<String, List<Employee>> r1 = map.entrySet().stream()
    .filter(i -> !i.getValue().isEmpty())
    .collect(Collectors.toMap(Map.Entry::getKey,
        i -> i.getValue().stream()
              .filter(e -> "M".equals(e.gender)).collect(Collectors.toList())));

To filter out entries where a list doesn't contain any "M" employee.

Map<String, List<Employee>> r3 = map.entrySet().stream()
    .filter(i -> i.getValue().stream().anyMatch(e -> "M".equals(e.gender)))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Let's have 2 entries in the map:

"1" -> ["M", "M", "M"]
"2" -> ["M", "F", "M"]

The results for them will be:

r1 = {1=[M, M, M], 2=[M, M]}
r2 = {1=[M, M, M]}
r3 = {1=[M, M, M], 2=[M, F, M]}
like image 78
Andrew Tobilko Avatar answered Nov 15 '22 00:11

Andrew Tobilko


In Java 8 you can convert a Map.entrySet() into a stream, follow by a filter() and collect() it. Example taken from here.

    Map<Integer, String> map = new HashMap<>();
    map.put(1, "linode.com");
    map.put(2, "heroku.com");

    //Map -> Stream -> Filter -> String
    String result = map.entrySet().stream()
        .filter(x -> "something".equals(x.getValue()))
        .map(x->x.getValue())
        .collect(Collectors.joining());

    //Map -> Stream -> Filter -> MAP
    Map<Integer, String> collect = map.entrySet().stream()
        .filter(x -> x.getKey() == 2)
        .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));

    // or like this
    Map<Integer, String> collect = map.entrySet().stream()
        .filter(x -> x.getKey() == 3)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

And for your case it would look like this, because you also need to find out if there is a match in a List of object of class Employee.

Map<String, List<Employee>> collect = map.entrySet().stream()
            .filter(x -> x.getValue().stream()
        .anyMatch(employee -> employee.Gender.equals("M")))
            .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
like image 36
AndrejH Avatar answered Nov 15 '22 00:11

AndrejH