louis amoros louis amoros - 1 year ago 108
Java Question

Java 8 stream Map<Long, List<MyClass>> to Map<Long, Set<Long>>

I would like to convert (using Java 8 stream) a

Map<Long, List<MyClass>>
in a
Map<Long, Set<Long>>
where the
represents the
of each
of the

I have tried:

.map(e -> e.getValue().stream()

But I cannot see how to get the result.

Answer Source

You are mapping instances of Map.Entry to Set<Long> instances which implies loosing track of the original map’s keys which makes it impossible to collect them into a new map having the same keys.

The first option is to map the Map.Entry<Long, List<MyClass>> instances to Map.Entry<Long, Set<Long>> instances and then collect the entries to a new map:

Map<Long, Set<Long>> result=
        .map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(),
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

The alternative is to fuse the map and collect step into one, to do the transformation right in the value function provided to the toMap collector:

Map<Long, Set<Long>> result=
        e -> e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet())));

This way, you avoid creating new Map.Entry instances and get more concise code, however, loose flexibility as you can’t chain additional stream operations in-between.