使用Java Stream API在Map<K,Map<V,X>>中将X类型转换为Y

我想从地图的地图转换内部地图。

旧地图:整数表示秒Map<String, Map<LocalDate, Integer>>

新地图:Map<String, Map<LocalDate, Duration>>

我已尝试创建新的内部地图,但收到错误

错误:java:找不到适合的方法的方法不适用putAll(java.util.stream.Stream<java.lang.Object>)java.util.Map.putAll(java.util.Map<? extends java.time.LocalDate,? extends java.time.Duration>)

oldMap.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getKey,
                e -> new HashMap<LocalDate, Duration>() {{
                    putAll(
                        e.getValue().entrySet().stream()
                            .map(x -> new HashMap.SimpleEntry<LocalDate, Duration>
                                (x.getKey(), Duration.ofSeconds(x.getValue())))
                    );
                }}
            ));

答案 1

如果你想要紧凑的代码,你可以使用

Map<String, Map<LocalDate, Duration>> newMap = new HashMap<>();
oldMap.forEach((s,o) -> o.forEach((d, i) ->
    newMap.computeIfAbsent(s, x->new HashMap<>()).put(d, Duration.ofSeconds(i))));

如果你想避免不必要的哈希操作,你可以把它扩展一点

Map<String, Map<LocalDate, Duration>> newMap = new HashMap<>();
oldMap.forEach((s,o) -> {
    Map<LocalDate, Duration> n = new HashMap<>();
    newMap.put(s, n);
    o.forEach((d, i) -> n.put(d, Duration.ofSeconds(i)));
});

答案 2

快速清洁

HashMap<String, HashMap<LocalDate, Duration>> newMap = new HashMap<>();
oldHashMap.forEach((key, innerMap) -> {
    HashMap<LocalDate, Duration> newStuff = new HashMap<>();
    innerMap.forEach((k2,v2) -> newStuff.put(k2,Duration.ofSeconds(v2)));
    newMap.put(key, newStuff);
});