首先我们先运行一个例子来分析

从例子中可以发现,hashmap毋庸置疑可以存储null键值对,hashtable和ConcurrentHashMap不可以存储null键值对,并且null值,null也不可以单独存储,其原因剖析源码如下:
1.HashTalble
2.ConcurrentHashMap

从分析中我们可以看到,hashtable,对于null值会抛出异常,而对于null键,则会调用null.hashCode(),而导致空指针异常,而concurrenthashmap则对于null键值对,直接抛出空异常,这也就是为什么他们存入null键值对抛出异常的原因.那么我们看看hashmap又是怎么做到存储null键值对


从上图我们可以看出对于key,它调用了hash方法,在其中对于null值,赋予了0值处理,对于null键,他直接存入了Node对象未进行任何处理,所以综上可以存储null键值对,但只能有一个null键,可以存入多个null值,要求其对应的key不同.
那么我就开始思考,为什么这样设计呢?后来翻阅很多资料和分析得出这样一个我个人觉得比较合理的结论:
ConcurrentHashmap和Hashtable都是线程安全用来做支持并发的,这样会有一个问题,当你通过get(k)获取对应的value时,如果获取到的是null时,你无法判断,它是put(k,v)的时候value为null,还是这个key从来没有做过映射。而HashMap是非并发的,可以通过contains(key)来做这个判断。而支持并发的Map在调用m.contains(key)和m.get(key),m很可能已经不同了
探讨HashMap、Hashtable和ConcurrentHashMap对null键值对的处理差异。HashMap通过特殊机制允许存储null键值,而Hashtable和ConcurrentHashMap因并发安全考虑禁止此操作,避免判断null值来源的不确定性。

363

被折叠的 条评论
为什么被折叠?



