【List转Map操作】Collectors.toMap语法分享(案例实践)

举报
辰兮 发表于 2022/03/23 00:20:59 2022/03/23
【摘要】 【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、...

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿大家奔赴在各自的热爱里…


一、初识Collectors.toMap

在真实的业务场景中有很多集合转map的操作,今天一起学习一下Collectors.toMap相关使用

创建一个house的对象

@Data
public class House {

    private Integer id;        //id
    private Integer ownerid;   //家主编号
    private String housename;  //家庭名称
    private String address;    //家庭地址
    
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

模拟数据

/**
 * @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='浙江杭州'}}
         */

    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

输出效果:同上
在这里插入图片描述
常见操作大家实践即可

houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename));

  
 
  • 1

语法详细学习:揭开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);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

参数含义分别是:

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

常见的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)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

解决办法:出现重复时,取前面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));

  
 
  • 1
  • 2

执行效果如下:不报错,正常的取值覆盖
在这里插入图片描述

对于结果的操作还有很多处理方法,如拼接等

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

  
 
  • 1

执行效果

{1=辰兮辰小兮, 2=辰兮要努力}

  
 
  • 1

具体的实践根据具体的业务来操作数据即可


记录辰兮的第200篇博客!明确的目标,执行,反思,精进!早日成为一名优秀的程序员!
请添加图片描述


非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!

2021年9月12日17:56:48 愿你们奔赴在自己的热爱里!

文章来源: blessing.blog.csdn.net,作者:辰兮要努力,版权归原作者所有,如需转载,请联系作者。

原文链接:blessing.blog.csdn.net/article/details/120253616

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。