I have the following code:
class Scratch {
public static void main(String[] args) {
Map<String, Id> idDefinitions = Map.of(
"A", new Id(Group.GROUP_A),
"B", new Id(Group.GROUP_B),
"C", new Id(Group.GROUP_A));
Map<String, Object> ids = Map.of("A", new Object(), "B", new Object(), "C", new Object());
Map<Group, Map<String, Object>> idsByGroup = ?
}
private static class Id {
private Group group;
public Id(Group group) {
this.group = group;
}
}
private enum Group {
GROUP_A,
GROUP_B
}
}
Based on the idDefinitions and the ids, I want to create a new Map where all the ids are grouped by their Group. I can solve that iteratively with a for-loop but I’m wondering if there are stream alternatives, using the groupingBy collector.
>Solution :
If you just use Collectors.groupingBy to group by Group. This will give you a Map<Group, List<Map.Entry<String, Id>>>
But we want the values of the map to be another Map, so we should pass a downstream collector to groupingBy, the toMap collector. The downstream is a stream of Map.Entry<String, Id>, so the maps’ keys would be entry.getKey, and the values would be the Objects from ids.
Map<Group, Map<String, Object>> idsByGroup = idDefinitions
.entrySet().stream()
.filter(x -> ids.containsKey(x.getKey()))
.collect(
Collectors.groupingBy(
x -> x.getValue().group,
Collectors.toMap(
Map.Entry::getKey,
x -> ids.get(x.getKey())
)
)
);