简体   繁体   English

使用java 8流从另一个地图地图构建地图地图

[英]Using java 8 streams to build a map of map from another map of map

I have a Map collection in java我在 java 中有一个 Map 集合

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

using java 8 I want to build a map of使用 java 8 我想建立一个地图

 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 Java 类

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.您需要在外部toMap中使用toMap的 3 参数版本,以避免在不同日期多次找到相同区域的键上发生冲突。

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>>您可以使用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;
        })
    );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM