4 回答

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

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個(gè)贊
這將是直截了當(dāng)?shù)模?/p>
listofA.stream().collect(toMap(Function.identity(), a -> getListofB(a)));

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

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