[英]Merging Map streams using Java 8 Lambda Expression
我有兩個Map<Integer, String>
類型的映射m1
和m2
,它們必須合並到一個映射Map<Integer, List<String>>
,其中兩個映射中相同鍵的值被收集到一個 List 和放入新地圖。
基於我探索的解決方案:
Map<Integer, List<String>> collated =
Stream.concat(m1.entrySet().stream(), m2.entrySet().stream()).collect(
Collectors.toMap(Entry::getKey,
Entry::getValue, (a, b) -> {
List<String> merged = new ArrayList<String>(a);
merged.addAll(b);
return merged;
}));
但是,這個解決方案期望源List
是Map<Integer, List<String>>
因為 toMap 中的合並函數期望操作數和結果是相同的類型。
我不想更改源集合。 請提供有關使用 lambda 表達式實現此目標的輸入。
這是groupingBy
收集器的工作:
Stream.of(m1,m2)
.flatMap(m->m.entrySet().stream())
.collect(groupingBy(
Map.Entry::getKey,
mapping(Map.Entry::getValue, toList())
));
我現在不能測試它,但我認為你需要它來將值的映射從Entry::getValue
更改為包含該值的 List :
Map<Integer, List<String>> collated =
Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.toMap(Entry::getKey,
e -> {
List<String> v = new ArrayList<String>();
v.add(e.getValue());
return v;
},
(a, b) -> {
List<String> merged = new ArrayList<String>(a);
merged.addAll(b);
return merged;
}));
編輯:這個想法是正確的。 語法不是。 當前語法有效,雖然有點難看。 必須有一種更短的方式來編寫它。
您還可以將e -> {..}
替換為e -> new ArrayList<String>(Arrays.asList(new String[]{e.getValue()}))
。
或使用e -> Stream.of(e.getValue()).collect(Collectors.toList())
或者你可以用groupingBy
來做到:
Map<Integer, List<String>> collated =
Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())));
這似乎是使用 Guava 的Multimap
的絕佳機會。
ListMultimap<Integer, String> collated = ArrayListMultimap.create();
collated.putAll(Multimaps.forMap(m1));
collated.putAll(Multimaps.forMap(m2));
如果你真的需要一個Map<Integer, List<String>>
:
Map<Integer, List<String>> mapCollated = Multimaps.asMap(collated);
為清楚起見,您可以使用帶有三個參數的Collectors.toMap
方法。
Map<Integer, String> m1 = Map.of(1, "A", 2, "B");
Map<Integer, String> m2 = Map.of(1, "C", 2, "D");
// two maps into one
Map<Integer, List<String>> m3 = Stream
.of(m1.entrySet(), m2.entrySet())
.flatMap(Collection::stream)
.collect(Collectors.toMap(
// key - Integer
e -> e.getKey(),
// value - List<String>
e -> List.of(e.getValue()),
// mergeFunction - two lists into one
(list1, list2) -> {
List<String> list = new ArrayList<>();
list.addAll(list1);
list.addAll(list2);
return list;
}));
// output
System.out.println(m3); // {1=[A, C], 2=[B, D]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.