I'm trying to take a map of type A -> A
, and group it into a map of A to List<A>
. (Also reversing the key-value relationship, but I don't think that is necessarily relevant).
This is what I have now:
private static Map<Thing, List<Thing>> consolidateMap(Map<Thing, Thing> releasedToDraft) {
// Map each draft Thing back to the list of released Things (embedded in entries)
Map<Thing, List<Map.Entry<Thing, Thing>>> draftToEntry = releasedToDraft.entrySet().stream()
.collect(groupingBy(
Map.Entry::getValue,
toList()
));
// Get us back to the map we want (Thing to list of Things)
return draftToEntry.entrySet().stream()
.collect(toMap(
Map.Entry::getKey,
ThingReleaseUtil::entriesToThings
));
}
private static List<Thing> entriesToThings(Map.Entry<Thing, List<Map.Entry<Thing, Thing>>> entry) {
return entry.getValue().stream()
.map(Map.Entry::getKey)
.collect(toList());
}
I'd like to do this in a single statement, and I feel like it must be possible to transform the Map<Thing, List<Map.Entry<Thing, Thing>>>
to Map<Thing, List<Thing>>
as part of the groupingBy
operation.
I've tried using reducing()
, custom collectors, everything I can find; but I'm stymied by the lack of complex examples out there, and the fact that the few similar ones I can find have List.of()
, which doesn't exist in Java 8 (Collections.singletonList()
does not appear to be a good replacement).
Could someone help me with what is probably the obvious?
Must be on the line of
private static Map<Thing, List<Thing>> consolidateMap(Map<Thing, Thing> releasedToDraft) {
return releasedToDraft.entrySet().stream()
.collect(groupingBy(
Map.Entry::getValue,
mapping(Map.Entry::getKey, toList())
));
}