• JAVA8 Collectors.toMap value为null报错


    2018年11月7日 17:59:27 该bug貌似在java9中修复,欢迎补充
    2019年3月19日 17:59:11 查看java11的toMap方法后,发现并没有修改任何实现
    2022年7月28日 18:02:44 stackoverflow上的讨论 jdk开发者的回答

    Caused by: java.lang.NullPointerException
    	java.util.HashMap.merge(HashMap.java:1224)
    	java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
    	java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
    	java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    	java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    	java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    	java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    原因是使用Map.merge方法合并时,merge不允许value为null导致的
    方法源码:

    default V merge(K key, V value,
                BiFunction remappingFunction) {
            Objects.requireNonNull(remappingFunction);
            //在这里判断了value不可为null
            Objects.requireNonNull(value);
            V oldValue = get(key);
            V newValue = (oldValue == null) ? value :
                       remappingFunction.apply(oldValue, value);
            if(newValue == null) {
                remove(key);
            } else {
                put(key, newValue);
            }
            return newValue;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    解决方案:

    Map videoGiftSumVoMap=videoGiftSum.stream().collect(Collectors.toMap
    (callRecodVo -> Optional.ofNullable(callRecodVo).map
    (CallRecodVo::getStatdate).orElse(0),callRecodVo -> Optional.ofNullable(callRecodVo).map
    (CallRecodVo::getVideogiftdiamond).orElse(0), (key1, key2) -> key2));
    
    • 1
    • 2
    • 3
    • 4

    使用optional判断空指针设置为null的默认值

    分析:
    因没有找到Map.merge方法为什么要检查Value Null的相关资料和官方回答,所以做以下推断:
    Collectors.toMap可以使用ConcurrentHashMap为最终收集结构,而ConcurrentHashMap不允许Value为Null避免产生二义性(ConcurrentHashMap的key value不能为null,map可以?)和CAS的ABA问题,所以Map.merge为了兼容ConcurrentHashMap还有ConcurrentSkipListMap等多线程环境下使用的数据结构和使用CAS的实现不允许Value为Null
    其他知识:key不能为null,是因为无法分辨是key没找到的原因所以为null,还是key值本身就为null。–key的二义性

  • 相关阅读:
    智慧图书馆中一般有哪些设备
    Selenium基础 — POM设计模式(一)
    杰理之涂鸦APP显示连接的设备【篇】
    GitHub SSH免密登录
    聊跨境:一年增长60%!人人都说跨境电商难做,但红利仍在(Starday)
    Python 面向对象编程之封装的艺术
    object类的一些方法
    python第一个接口返回的数据作为第二个接口的参数
    进程间的通信方式
    每日几道LeetCode练习
  • 原文地址:https://blog.csdn.net/jiong9412/article/details/126725325