使用lambda表达式Collectors.toMap 遇到的报错,带有源码分析

发布于:2024-04-24 ⋅ 阅读:(31) ⋅ 点赞:(0)
概述

正常hashMap中的key和value都允许为null,但是在list转map中,使用lambda表达式要求key和value都不能为null。这很反常识

起因

本身上游返回contentId和traceId 内容id和跟踪id,但是项目人员变动修改了接口没有给traceId导致

代码
public class test1 {
    public static void main(String[] args) {
        Hello hello1 = new Hello();
        hello1.setId(1);
        hello1.setValue("1");
        Hello hello2 = new Hello();
        hello2.setId(2);
        hello2.setValue(null);
        ArrayList<Hello> list = new ArrayList<>();
        list.add(hello1);
        list.add(hello2);
        Map<Integer, String> map = list.stream()
                .collect(Collectors.toMap(vo -> vo.getId(), vo -> vo.getValue(), (v1, v2) -> v1));
    }

    static class Hello {

        int id;
        String value;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

在merger的时候进行了判空
在这里插入图片描述

解决方案1 map给空设默认值或者是过滤掉

Map<Integer, String> map = list.stream().map(vo -> {
            if (vo.getValue() == null) {
                vo.setValue("default");
            }
            return vo;
        }).collect(Collectors.toMap(vo -> vo.getId(), vo -> vo.getValue(), (v1, v2) -> v1));

   Map<Integer, String> map = list.stream().filter(vo -> vo.getValue() == null)
                .collect(Collectors.toMap(vo -> vo.getId(), vo -> vo.getValue(), (v1, v2) -> v1));

    HashMap<Integer, String> m5 = list.stream().collect(
                Collectors.toMap(vo -> vo.getId(), vo -> Optional.ofNullable(vo.getValue()).orElse("default"), (a, b) -> b, HashMap::new));

解决方案2 自己collect 定义supplier,accumulator,combiner
        HashMap<Integer, String> m3 = list.stream()
                .collect(HashMap::new
                        , (map, item) -> map.put(item.getId(), item.getValue())
                        , HashMap::putAll);
        // 上面是简写版本,下面是揉开来的版本
        HashMap<Integer, String> m4 = list.stream()
                .collect(
                        () -> {
                            return new HashMap<Integer, String>();   // 这里定义了一个对象,相当于下面map,map1,map2的数据类型
                        }
                        , (map, item) -> map.put(item.getId(), item.getValue())
                        , (map1, map2) -> {
                            map1.putAll(map2);
                        });

在这里插入图片描述
这里有supplier,accumulator,combiner

      Map<Integer, String> map5 = list.stream().filter(vo -> vo.getValue() == null)
                .collect(Collectors.toMap(vo -> vo.getId(), vo -> vo.getValue(), (v1, v2) -> v1));
这里的写法点进Collectors.toMap

在这里插入图片描述
进入toMap
在这里插入图片描述

Supplier mapFactory 相当于HashMap::new
accumulator 相当于 (map, item) -> map.put(item.getId(), item.getValue()) 也相当于 (map, item) -> map.put(item.getId(), item.getValue())
mapMerger(mergeFunction) 相当于 map1.putAll(map2); 也相当于HashMap::putAll