【Java基础】ConcurrentHashMap为什么不能存null键和null值

代码如下

    /**
     * 测试ConcurrentHashMap null键和null值的问题
     * @return
     */
    @RequestMapping(value = "/get_nacos")
    public String getNacos(){
        ConcurrentHashMap<String,String> map =new ConcurrentHashMap<>(1);
        map.put("testKey", null);
        String nullValue = map.get("sss");
        return nullValue;
    }
}

其中在执行put操作时,会报错,信息如下:

java.lang.NullPointerException: null
    at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011) ~[na:1.8.0_162]
    at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006) ~[na:1.8.0_162]
    at com.gabriel.stage.controller.TestController.getNacos(TestController.java:44) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]

那么这里就有一个疑问了,为什么HashMap能存null键和null值,ConcurrentHashMap就不能存null键和null值了呢,并且还会出现空指针异常

个人理解如下:

  ConrrentHashMap 是一个用于多线程并发场景下的并发容器(Map),也就是在多线程环境下执行增删改查方法要保证线程安全性,

  例如containsKey()方法中

    public boolean containsKey(Object key) {
        return get(key) != null;
    }

  该方法会调用get方法去查询key值是否存在,此时如果key值是我们手动存进去的,这个时候就会在代码语义上有区别,无法区分是真的没有该key 还是我们存储的key,

  并且在调用get()方法时,可能会出现别的线程修改为null键和null值的情况,这中情况在并发场景下会产生歧义;

  

   HashMap本身是一个线程不安全的容器(Map),也就是使用场景局限于单线程环境,因此存储null键null值 通常不会有什么问题,

   HashMap将存储的null键存储到数组的第1个元素;

原文地址:https://www.cnblogs.com/july-sunny/p/13544010.html