我有一個嵌套映射列表(List<Map<String, Map<String, Long>>>
),目標是將列表縮小爲單個映射,並且要完成合並如下:如果map1
包含x->{y->10, z->20}
和map2
包含x->{y->20, z->20}
那麼這兩個應合併爲x->{y->30, z->40}
。使用Java 8流操作符將兩個級別映射的列表縮減爲單個兩級映射
我試圖做到這一點,這是工作正常。
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
public class Test {
public static void main(String args[]) throws IOException {
Map<String, Map<String, Long>> data1 = new HashMap<>();
Map<String, Long> innerData1 = new HashMap<>();
innerData1.put("a", 10L);
innerData1.put("b", 20L);
data1.put("x", innerData1);
Map<String, Long> innerData2 = new HashMap<>();
innerData2.put("b", 20L);
innerData2.put("a", 10L);
data1.put("x", innerData1);
Map<String, Map<String, Long>> data2 = new HashMap<>();
data2.put("x", innerData2);
List<Map<String, Map<String, Long>>> mapLists = new ArrayList<>();
mapLists.add(data1);
mapLists.add(data2);
Map<String, Map<String, Long>> result = mapLists.stream().flatMap(map -> map.entrySet().stream()).
collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, new BinaryOperator<Map<String, Long>>() {
@Override
public Map<String, Long> apply(Map<String, Long> t,
Map<String, Long> u) {
Map<String, Long> result = t;
for(Entry<String, Long> entry: u.entrySet()) {
Long val = t.getOrDefault(entry.getKey(), 0L);
result.put(entry.getKey(), val + entry.getValue());
}
return result;
}
}));
}
}
有沒有其他更好的和有效的方法來解決這個問題?
如果嵌套級別大於2,如何更乾淨地做到這一點?假設列表類似List<Map<String, Map<String, Map<String, Long>>>>
,我們必須將其減少到單個Map<String, Map<String, Map<String, Long>>>
,假設類似於上面的合併功能。
StreamEx通常更簡單的方法:)。 – Tunaki
@Tunaki實際上會更簡單些[JDK-8072718](https://bugs.openjdk.java.net/browse/JDK-8072718)。 –