使用Java 8流从另一个地图映射构建一个地图映射

时间:2020-10-01 15:02:55

标签: java java-8

我在Java中有一个Map集合

Map<AreaDate, Map<AreaCategory, List<Location>> dateWiseAreas

使用Java 8我想构建一个地图

 Map<Area, Map<AreaCategory, List<Location>> areas

我使用了以下逻辑,并且出现重复键错误,提示区域键重复

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类

Area {
   EUROPE,
   AUSTRALIA,
   ASIA;   
}


AreaDate {
 Area area;
 LocalDate date;
 int priority;
}

AreaCategory {
  NORTH,
  SOUTH,
  WEST,
  EAST;
}

Location {
 int xaxis;
 int yaxis;
}

2 个答案:

答案 0 :(得分:0)

您需要在外部集合中使用toMap的3个参数版本,以避免在多次使用相同日期多次发现相同区域的键上发生冲突。

(未经测试)

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
));

答案 1 :(得分:0)

您可以使用toMap()的重载,它允许您传递BinaryOperator<V>,其中V的情况是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;
        })
    );