Prpaa
Prpaa

Reputation: 245

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 Strings of the value Lists 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 Lists consist only of Strings of length larger than 5?

  3. A Map<String, Long> with counts of Strings 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

Upvotes: 2

Views: 379

Answers (1)

Eran
Eran

Reputation: 394156

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

Upvotes: 5

Related Questions