天天看點

【List轉Map操作】Collectors.toMap文法分享(案例實踐)

【辰兮要努力】:hello你好我是辰兮,很高興你能來閱讀,昵稱是希望自己能不斷精進,向着優秀程式員前行!

部落格來源于項目以及程式設計中遇到的問題總結,偶爾會有讀書分享,我會陸續更新Java前端、背景、資料庫、項目案例等相關知識點總結,感謝你的閱讀和關注,希望我的部落格能幫助到更多的人,分享擷取新知,大家一起進步!

吾等采石之人,應懷大教堂之心,願大家奔赴在各自的熱愛裡…

文章目錄

      • 一、初識Collectors.toMap
      • 二、深入Collectors.toMap

一、初識Collectors.toMap

在真實的業務場景中有很多集合轉map的操作,今天一起學習一下Collectors.toMap相關使用

建立一個house的對象

@Data
public class House {

    private Integer id;        //id
    private Integer ownerid;   //家主編号
    private String housename;  //家庭名稱
    private String address;    //家庭位址
    
}
           

模拟資料

/**
 * @description: List 轉 Map 操作
 * @author: 辰兮要努力
 * @create: 2021-09-11 12:57
 */
public class ListToMap {

    public static void main(String[] args) {
        House house = new House(1,1,"辰兮","北京海澱");
        House house1 = new House(2,2,"辰兮要努力","湖北武漢");
        House house2 = new House(3,3,"辰小兮","浙江杭州");
        ArrayList<House> houses = new ArrayList<>();
        houses.add(house);
        houses.add(house1);
        houses.add(house2);
        //在實際項目中我們經常會用到 List 轉 Map 操作 ->過去是for循環的操作,現在可以學習如下的方法Collectors.toMap
        /**
         * 我們收集一下集合中每個對象的兩個單獨的屬性
         */
        Map<String, String> mapHouse = houses.stream().collect(Collectors.toMap(House::getHousename, House::getAddress));
        System.out.println(mapHouse);
        //{辰兮要努力=湖北武漢, 辰小兮=浙江杭州, 辰兮=北京海澱}
        
        /**
         * 前後的屬性的資料類型要對應  一般時間業務中收集帶有唯一表示的業務資料
         */
        Map<Integer, String> map = houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename));
        System.out.println(map);
        //{1=辰兮, 2=辰兮要努力, 3=辰小兮}

        /**
         * 收集一下屬性和對象本身
         */
        Map<Integer, House> houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerid, o -> o));
        Map<Integer, House> houseMap1 = houses.stream().collect(Collectors.toMap(House::getOwnerid,  Function.identity()));
        System.out.println(houseMap);
       /**
         * {1=House{id=1, ownerid=1, housename='辰兮', address='北京海澱'}, 
         * 2=House{id=2, ownerid=2, housename='辰兮要努力', address='湖北武漢'}, 
         * 3=House{id=3, ownerid=3, housename='辰小兮', address='浙江杭州'}}
         */
         
        //業務場景:一般會根據具體的鍵值 取具體的對象
        System.out.println(houseMap.get(1));
        //House{id=1, ownerid=1, housename='辰兮', address='北京海澱'}
        
        //此處的效果同houseMap
        System.out.println(houseMap1);
       /**
         * {1=House{id=1, ownerid=1, housename='辰兮', address='北京海澱'}, 
         * 2=House{id=2, ownerid=2, housename='辰兮要努力', address='湖北武漢'}, 
         * 3=House{id=3, ownerid=3, housename='辰小兮', address='浙江杭州'}}
         */

    }

}
           

輸出效果:同上

【List轉Map操作】Collectors.toMap文法分享(案例實踐)

常見操作大家實踐即可

文法詳細學習:揭開System.out::println的神秘面紗

二、深入Collectors.toMap

Collectors.toMap 有三個重載方法:

toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
        BinaryOperator<U> mergeFunction);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
        BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);
           

參數含義分别是:

keyMapper:Key 的映射函數

valueMapper:Value 的映射函數

mergeFunction:當 Key 沖突時,調用的合并方法

mapSupplier:Map 構造器,在需要傳回特定的 Map 時使用

業務場景最多的還是map的鍵為一個唯一的辨別符,值為對象本身!

如果希望得到 Map 的 value 為對象本身時,可以這樣寫

/**
         * 收集一下屬性和對象本身
         */
Map<Integer, House> houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerid, o -> o));
Map<Integer, House> houseMap1 = houses.stream().collect(Collectors.toMap(House::getOwnerid,  Function.identity()));
           

常見的java.lang.IllegalStateException: Duplicate key 問題處理

【List轉Map操作】Collectors.toMap文法分享(案例實踐)

線上業務代碼出現Duplicate Key的異常,影響了業務邏輯,檢視抛出異常部分的代碼

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 辰兮
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1254)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.example.cwgl.ListToMap.main(ListToMap.java:28)
           

解決辦法:出現重複時,取前面value的值,或者取後面放入的value值,則覆寫先前的value值

houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename,(v1,v2)->v2));
houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename,(v1,v2)->v1));
           

執行效果如下:不報錯,正常的取值覆寫

【List轉Map操作】Collectors.toMap文法分享(案例實踐)

對于結果的操作還有很多處理方法,如拼接等

執行效果

具體的實踐根據具體的業務來操作資料即可

記錄辰兮的第200篇部落格!明确的目标,執行,反思,精進!早日成為一名優秀的程式員!

【List轉Map操作】Collectors.toMap文法分享(案例實踐)

非常感謝你閱讀到這裡,如果這篇文章對你有幫助,希望能留下你的點贊👍 關注❤️ 分享👥 留言💬thanks!!!

2021年9月12日17:56:48 願你們奔赴在自己的熱愛裡!

繼續閱讀