【辰兮要努力】: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='浙江杭州'}}
*/
}
}
輸出效果:同上
常見操作大家實踐即可
文法詳細學習:揭開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 問題處理
線上業務代碼出現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));
執行效果如下:不報錯,正常的取值覆寫
對于結果的操作還有很多處理方法,如拼接等
執行效果
具體的實踐根據具體的業務來操作資料即可
記錄辰兮的第200篇部落格!明确的目标,執行,反思,精進!早日成為一名優秀的程式員!
非常感謝你閱讀到這裡,如果這篇文章對你有幫助,希望能留下你的點贊👍 關注❤️ 分享👥 留言💬thanks!!!
2021年9月12日17:56:48 願你們奔赴在自己的熱愛裡!