亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Collectors.toMap 或 groupingBy 在 Map 中收集映射操作的結果

使用 Collectors.toMap 或 groupingBy 在 Map 中收集映射操作的結果

MMMHUHU 2023-09-20 15:18:26
我有一個類型列表List<A>,并通過映射操作獲取合并在一個列表中的所有 A 元素的類型的集體列表List<B>。List<A> listofA = [A1, A2, A3, A4, A5, ...]List<B> listofB = listofA.stream()  .map(a -> repo.getListofB(a))  .flatMap(Collection::stream)  .collect(Collectors.toList());沒有平面圖List<List<B>> listOflistofB = listofA.stream()  .map(a -> repo.getListofB(a))  .collect(Collectors.toList());我想將結果收集為類型地圖Map<A, List<B>>,到目前為止嘗試使用各種Collectors.toMap或Collectors.groupingBy選項,但無法獲得所需的結果。
查看完整描述

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())));


查看完整回答
反對 回復 2023-09-20
?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

這將是直截了當的,

listofA.stream().collect(toMap(Function.identity(), a -> getListofB(a)));


查看完整回答
反對 回復 2023-09-20
?
料青山看我應如是

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)。


查看完整回答
反對 回復 2023-09-20
?
米琪卡哇伊

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)


查看完整回答
反對 回復 2023-09-20
  • 4 回答
  • 0 關注
  • 233 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號