I have a Map collection in java
Map<AreaDate, Map<AreaCategory, List<Location>> dateWiseAreas
using java 8 I want to build a map of
Map<Area, Map<AreaCategory, List<Location>> areas
I used the below logic and I get a duplicate key error saying Area key is duplicate
Map<Area, Map<AreaCategory, List<Location>> areas = dateWiseAreas.entrySet().stream()
.collect(toMap(k -> k.getKey().area(),
v -> v.getValue()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey(), Map::Entry::getValue,
(oldValue,newValue) -> oldValue, LinkedHashMap::new))));
Java classes
Area {
EUROPE,
AUSTRALIA,
ASIA;
}
AreaDate {
Area area;
LocalDate date;
int priority;
}
AreaCategory {
NORTH,
SOUTH,
WEST,
EAST;
}
Location {
int xaxis;
int yaxis;
}
You need to use the 3 argument version of toMap
in the outer collect to avoid conflict on keys where the same area is found multiple times with different dates.
Something like (untested)
Map<Area, Map<AreaCategory, List<Location>> areas = dateWiseAreas.entrySet().stream()
.collect(toMap(k -> k.getKey().area(),
v -> v.getValue()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey(), Map::Entry::getValue,
(oldValue,newValue) -> oldValue, LinkedHashMap::new)),
(oldValue, newvalue) -> oldValue
));
You can use the overload of toMap()
which allows you to pass a BinaryOperator<V>
where V
in your case is Map<AreaCategory, List<Location>>
Map<Area, Map<AreaCategory, List<Location>> areas = dateWiseAreas.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey().area(),
Map.Entry::getValue, // there seems to be no need to copy the whole thing again
(a, b) -> {
// merging Map b into Map a
b.forEach((key, values) -> a.merge(key, values, (c, d) -> {
// adding all locations from d to a
c.addAll(d);
return c;
});
return b;
})
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.