Search code examples
javajava-8java-streamcollect

Convert Set<V> to Map<String, Set<String>


I have following collection:

Set<Map.Entry<Event, Long>> entries

Event POJO:

public class Event{
    private long epoch; 
    private List<Pair<String, String> eventParams; 
}

I want to convert entries collection to Map<String, Set<String>>

Example:

List<Pair<String, String> eventParams = Arrays.asList(Pair.of("abc","123"), Pair.of("abc","456"));

Converted collection:

Map<String, Set<String>> converted = ["abc", ["123", "456"]]

I tried following:

entries.stream().flatMap(x -> x.getKey().getEventParams().stream())
            .collect(Collectors.groupingBy(Pair::getKey, Collectors.toSet(Pair::getValue)));

However, I am getting error: toSet in Collectors cannot be applied.

What is the correct way of doing this ?


Solution

  • Replace

    Collectors.toSet(Pair::getValue)
    

    with

    Collectors.mapping(Pair::getValue, Collectors.toSet())
    

    The problem is that Collectors.toSet() doesn't have any parameters, it operates on the type defined by the input stream. Collectors.mapping(mapper, downstream) alters this behaviour by "applying a mapping function to each input element before accumulation".