• Collectors.toMap应用


    文章目录

    Collectors.toMap介绍

    在真实的业务场景中有很多集合转map的操作,例如

    @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 操作
     */
    public class ListToMap {
    
        public static void main(String[] args) {
            House house = new House(1,1,"aa","北京海淀");
            House house1 = new House(2,2,"bb","湖北武汉");
            House house2 = new House(3,3,"cc","浙江杭州");
            ArrayList houses = new ArrayList<>();
            houses.add(house);
            houses.add(house1);
            houses.add(house2);
            //在实际项目中我们经常会用到 List 转 Map 操作 ->过去是for循环的操作,现在可以学习如下的方法Collectors.toMap
            /**
             * 我们收集一下集合中每个对象的两个单独的属性
             */
            Map mapHouse = houses.stream().collect(Collectors.toMap(House::getHousename, House::getAddress));
            System.out.println(mapHouse);
            //{aa=湖北武汉, bb=浙江杭州, cc=北京海淀}
            
            /**
             * 前后的属性的数据类型要对应  一般时间业务中收集带有唯一表示的业务数据
             */
            Map map = houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename));
            System.out.println(map);
            //{1=aa, 2=bb, 3=cc}
    
            /**
             * 收集一下属性和对象本身
             */
            Map houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerid, o -> o));
            Map houseMap1 = houses.stream().collect(Collectors.toMap(House::getOwnerid,  Function.identity()));
            System.out.println(houseMap);
           /**
             * {1=House{id=1, ownerid=1, housename='aa', address='北京海淀'}, 
             * 2=House{id=2, ownerid=2, housename='bb', address='湖北武汉'}, 
             * 3=House{id=3, ownerid=3, housename='cc', address='浙江杭州'}}
             */
             
            //业务场景:一般会根据具体的键值 取具体的对象
            System.out.println(houseMap.get(1));
            //House{id=1, ownerid=1, housename='aa', address='北京海淀'}
            
            //此处的效果同houseMap
            System.out.println(houseMap1);
           /**
             * {1=House{id=1, ownerid=1, housename='aa', address='北京海淀'}, 
             * 2=House{id=2, ownerid=2, housename='bb', address='湖北武汉'}, 
             * 3=House{id=3, ownerid=3, housename='cc', 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

    常见操作大家实践即可

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

    深入Collectors.toMap

    Collectors.toMap 有三个重载方法:

    toMap(Function keyMapper, Function valueMapper);
    toMap(Function keyMapper, Function valueMapper,
            BinaryOperator mergeFunction);
    toMap(Function keyMapper, Function valueMapper,
            BinaryOperator mergeFunction, Supplier mapSupplier);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    参数含义分别是:

    keyMapper:Key 的映射函数

    valueMapper:Value 的映射函数

    mergeFunction:当 Key 冲突时,调用的合并方法

    mapSupplier:Map 构造器,在需要返回特定的 Map 时使用

    业务场景最多的还是map的键为一个唯一的标识符,值为对象本身!

    如果希望得到 Map 的 value 为对象本身时,可以这样写

           /**
             * 收集一下属性和对象本身
             */
    Map houseMap = houses.stream().collect(Collectors.toMap(House::getOwnerid, o -> o));
    Map houseMap1 = houses.stream().collect(Collectors.toMap(House::getOwnerid,  Function.identity()));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    常见的java.lang.IllegalStateException: Duplicate key 问题处理

    我们把做的测试数据 House house = new House(1,1,“aa”,“北京海淀”);
    House house1 = new House(2,2,“bb”,“湖北武汉”);
    House house2 = new House(3,3,“cc”,“浙江杭州”);
    house2修改为: House house2 = new House(3,1,“cc”,“浙江杭州”);
    这样Ownerid会重复
    当我们执行如下代码时:houses.stream().collect(Collectors.toMap(House::getOwnerid, House::getHousename);
    会出错,java.lang.IllegalStateException: Duplicate key

    线上业务代码出现Duplicate Key的异常,影响了业务逻辑,查看抛出异常部分的代码

    Exception in thread "main" java.lang.IllegalStateException: Duplicate key aa
    	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));
    具体的实践根据具体的业务来操作数据即可

  • 相关阅读:
    Kotlin学习笔记之基础篇一
    【每日前端面经】2024-03-11
    全新升级的AOP框架Dora.Interception[6]: 框架设计和实现原理
    Jupyter介绍和安装使用
    软考中级软件设计师--6.设计模式
    网络安全(黑客)自学
    洛谷P1242 新汉诺塔
    异行星平台--CRM系统搭建
    ESP32 入门笔记07: ESP-NOW (ESP32 for Arduino)
    局域网综合设计-----计算机网络
  • 原文地址:https://blog.csdn.net/web13985085406/article/details/126326954