Reputation: 286
Let's say I got Map<ID, Object>
when looping over the entries via .entrySet().stream()
I want to map it to Map<String, List<Map<String, Object>>
When using toMap()
I change the ID of my initial map to a String (with a database call), but different ID's can return the same string so there can be duplicates. Is it possible if my key already exists in the toMap of my new map that I'm collecting, that my ObjectOne is added in a new list entry of my new map in the format of Map<String, List<Map<String, Object>>
.
I tried stuff with Collectors.groupingBy()
and Collectors.mapping()
but not getting it to work, curious if there is a way to do this
What I got now is the following solution, but I would like to collect it to map without having to define it first:
Map<String, List<Map<String, Object>>> giantMap = new HashMap<>();
initalMap.forEach((id, object) -> {
Code code = repository.getCodeById(id);
giantMap.computeIfAbsent(code, ignore -> new ArrayList<>())
.add(object);
});
Upvotes: 1
Views: 1398
Reputation: 19565
So, let's assume there is a map of some ids to objects of type ObjectOne
: Map<ID, ObjectOne>
.
The key IDs are converted to some Code
type by a database call, and the ObjectOne
values of the first map are just collected into another map using Collectors.groupingBy
and Collectors.mapping
as intended initially:
Map<ID, ObjectOne> initialMap = ...;
Map<Code, List<ObjectOne>> mapByCode = initialMap
.entrySet()
.stream() // Stream<Map.Entry<ID, ObjectOne>>
.collect(Collectors.groupingBy(
e -> repository.getCodeById(e.getKey()),
Collectors.mapping(Map.Entry::getValue, Collectors.toList())
));
Also, a keySet
of the initial map may be iterated upon:
// or using keySet()
Map<Code, List<ObjectOne>> mapByCode2 = initialMap
.keySet()
.stream() // Stream<ID>
.collect(Collectors.groupingBy(
repository::getCodeById,
Collectors.mapping(initialMap::get, Collectors.toList())
));
Upvotes: 3