Ale*_*191 17 java dictionary java-8 java-stream collectors
我想从地图地图转换内部地图.
旧地图: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())))
);
}}
));
Run Code Online (Sandbox Code Playgroud)
Hol*_*ger 11
如果你想要紧凑的代码,你可以使用
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))));
Run Code Online (Sandbox Code Playgroud)
如果要避免不必要的哈希操作,可以稍微扩展一下
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)));
});
Run Code Online (Sandbox Code Playgroud)
快速而干净
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);
});
Run Code Online (Sandbox Code Playgroud)
还有一个......
Map<String, Map<LocalDate, Duration>> newMap = map.entrySet().stream().collect(
Collectors.toMap(Entry::getKey,
entry -> entry.getValue().entrySet().stream().collect(
Collectors.toMap(Entry::getKey, e -> Duration.ofSeconds(e.getValue())))));
Run Code Online (Sandbox Code Playgroud)
我的两分钱,创建一个方法转换Map<K, V1>为Map<K, V2>:
public static <K,V1,V2> Map<K, V2> transformValues(final Map<K, V1> input, final Function<V1,V2> transform) {
Function<Map.Entry<K, V1>, V2> mapper = transform.compose(Map.Entry::getValue);
return input.entrySet().stream()
.collect(toMap(Map.Entry::getKey, mapper));
}
Run Code Online (Sandbox Code Playgroud)
然后你的代码变成:
Map<String, Map<LocalDate, Duration>> transformed
= transformValues(maps, map -> transformValues(map, Duration::ofSeconds));
Run Code Online (Sandbox Code Playgroud)
我更愿意迭代旧地图的条目并流过内部地图:
for (Entry<String, Map<LocalDate, Integer>> entry : oldMap.entrySet()) {
Map<LocalDate, Duration> asDuration = entry.getValue().entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(), e -> Duration.ofSeconds(e.getValue().longValue())));
newMap.put(entry.getKey(), asDuration);
}
Run Code Online (Sandbox Code Playgroud)
否则你需要在你的内部有第二个流collect:
newMap = oldMap.entrySet().stream()
.collect(Collectors.toMap(s -> s.getKey(), s -> s.getValue().entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(), e -> Duration.ofSeconds(e.getValue().longValue())))));
Run Code Online (Sandbox Code Playgroud)