Prpaa Prpaa - 1 month ago 10
Java Question

How to Stream a Map by value which is a Collection?

How to stream a

Map<String, List<String>>
to get:


  1. A
    List<String>
    of all the
    String
    s of the value
    List
    s of the
    Map
    which are longer than 5 characters? How to get long count of these?

  2. A
    Map<String, List<String>>
    where keys stay the same, but the
    List
    s consist only of
    String
    s of length larger than 5?

  3. A
    Map<String, Long>
    with counts of
    String
    s longer than 5 in
    List
    per map's key?



I started something but I am stuck:

long l = map.entrySet().stream()
.filter(m -> m.getValue().stream().filter(s -> s.length() > 5)


Thanks

Answer

For the first question, you can merge the Lists using flatMap and then filter out the short Strings :

List<String> longStrings = 
    map.values()
       .stream()
       .flatMap(Collection::stream)
       .filter(s->s.length() > 5)
       .collect(Collectors.toList());

For the second question, it looks like you want to create a new Map from the source Map, where the keys remain the same and the values are filtered :

Sample input :

Map<String, List<String>> map = new HashMap<> ();
map.put ("one", Arrays.asList (new String[]{"1","2","12345","123456"}));
map.put ("two", Arrays.asList (new String[]{"1","123456","12345","12"}));
map.put ("three", Arrays.asList (new String[]{"1","2","12","34"}));
map.put ("four", Arrays.asList (new String[]{"12345","123456","1234567","123"}));

Processing :

Map<String, List<String>> output =
    map.entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getKey,
                                 e->e.getValue()
                                     .stream()
                                     .filter(s -> s.length() > 5)
                                     .collect(Collectors.toList())));

Output :

{four=[123456, 1234567], one=[123456], three=[], two=[123456]}

The third question is a minor variation of the second :

Map<String, Long> output =
    map.entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getKey,
                                 e->e.getValue()
                                     .stream()
                                     .filter(s -> s.length() > 5)
                                     .count()));