4 回答

TA貢獻1777條經驗 獲得超3個贊
您可以將toMap
收集器與有界方法引用一起使用來獲取您需要的內容。另請注意,此解決方案假設您的源容器中沒有重復的 A 實例。如果該前提條件成立,則該解決方案將為您提供所需的結果。它看起來是這樣的。
Map<A, Collection<B>> resultMap = listofA.stream() .collect(Collectors.toMap(Function.identity(), repo::getListofB);
如果您有重復的 A 元素,那么除了上面給出的功能之外,您還必須使用此合并功能。合并功能可以處理鍵沖突(如果有)。
Map<A, Collection<B>> resultMap = listofA.stream() .collect(Collectors.toMap(Function.identity(), repo::getListofB, (a, b) -> { a.addAll(b); return a; }));
這里有一個更簡潔的 Java9 方法,它使用flatMapping
收集器來處理重復的 A 元素。
Map<A, List<B>> aToBmap = listofA.stream() .collect(Collectors.groupingBy(Function.identity(), Collectors.flatMapping(a -> getListofB(a).stream(), Collectors.toList())));

TA貢獻1772條經驗 獲得超5個贊
這將是直截了當的,
listofA.stream().collect(toMap(Function.identity(), a -> getListofB(a)));

TA貢獻1772條經驗 獲得超8個贊
在這個答案中,我將展示如果列表中有重復A
元素會發生什么List<A> listofA
。
實際上,如果 中存在重復項listofA
,下面的代碼將拋出一個IllegalStateException
:
Map<A,?Collection<B>>?resultMap?=?listofA.stream() ????????.collect(Collectors.toMap( ????????????????????????????Function.identity(),? ????????????????????????????repo::getListofB);
可能會拋出異常,因為當鍵中存在沖突時Collectors.toMap
不知道如何合并Function.identity()
值(即當鍵映射器函數返回重復項時,如果列表中存在重復元素就會出現這種情況listofA
)。
文檔中明確指出了這一點:
如果映射的鍵包含重復項(根據
Object.equals(Object)
),則IllegalStateException
在執行收集操作時會拋出異常。如果映射的鍵可能有重復項,請使用toMap(Function, Function, BinaryOperator
) 代替。
文檔還為我們提供了解決方案:如果存在重復元素,我們需要提供一種合并值的方法。這是一種這樣的方式:
Map<A,?Collection<B>>?resultMap?=?listofA.stream() ????????.collect(Collectors.toMap( ????????????????????????????Function.identity(),? ????????????????????????????a?->?new?ArrayList<>(repo.getListofB(a)), ????????????????????????????(left,?right)?->?{ ????????????????????????????????left.addAll(right);?? ??????????????????????????????????????????????????????????????return?left; ????????????????????????????});
Collectors.toMap
它使用接受合并函數作為其第三個參數的重載版本。在合并函數中,Collection.addAll
用于將B
每個重復A
元素的元素添加到每個 的唯一列表中A
。
在值映射器函數中,ArrayList
創建了一個新值,因此List<B>
每個值的原始值A
都不會發生變化。另外,當我們創建一個 時Arraylist
,我們提前知道它可以被改變(即我們可以稍后向其中添加元素,以防 中存在重復項listofA
)。

TA貢獻1998條經驗 獲得超6個贊
要收集一個Map
其中鍵是A
未更改的對象,值是對應B
對象的列表,可以將toList()
收集器替換為以下收集器:
toMap(Function.identity(), a -> repo.getListOfB(a))
第一個參數定義如何從原始對象計算密鑰identity()
:保持流的原始對象不變。
第二個參數定義了如何計算該值,因此這里它僅包含對將 a 轉換A
為 的列表的方法的調用B
。
由于該repo
方法僅采用一個參數,因此您還可以通過用方法引用替換 lambda 來提高清晰度:
toMap(Function.identity(), repo::getListOfB)
添加回答
舉報