Tim B.
Tim B.

Reputation: 466

From Map<String, Set<Integer>> collect values from a Set<String> of keys

I am trying to use map to map a set of keys into a Map of String to Set of Integer. Ideally I want to get all the value sets and collect them into a single set.

Lets say I have:

Map<String, List<Integer>> keyValueMap = new HashMap<>();
Set<String> keys = new HashSet<>();
Set<String> result = new HashSet<>();

I have tried:

result.addAll(keys.stream().map(key -> keyValueMap.get(key)).collect(Collectors.toSet());

This nets me an error saying addAll() is not applicable for the type Set>. I have tried replacing map() with flatMap() but I can't seem to get the syntax right if that is the solution.

What is the correct syntax to make this work?

Thanks!

Upvotes: 1

Views: 528

Answers (1)

Jacob G.
Jacob G.

Reputation: 29700

It looks like the type of result should be Set<Integer> instead of Set<String>.


With your snippet, you're attempting to invoke Set#addAll on a Set<Integer>, but the argument being passed is a Set<List<Integer>>, which doesn't compile.

To ameliorate your issue, one solution is to use flatMap instead of map:

result.addAll(keys.stream()
                  .flatMap(key -> keyValueMap.get(key).stream())
                  .collect(Collectors.toSet()));

A logically equivalent snippet is:

result.addAll(keys.stream()
                  .map(keyValueMap::get)
                  .flatMap(List::stream)
                  .collect(Collectors.toSet()));

Another solution would be to utilize Map#values:

result.addAll(keyValueMap.values().stream()
                         .flatMap(List::stream)
                         .collect(Collectors.toSet()));

Upvotes: 2

Related Questions