先假定ConcurrentHashMap也可以存放value为null的值。那不管是HashMap还是ConcurrentHashMap调用map.get(key)的时候,如果返回了null,那么这个null,都有两重含义:
**1.这个key从来没有在map中映射过。
**2.这个key的value在设置的时候,就是null。
在非线程安全的map集合(HashMap)中可以使用map.contains(key)方法来判断,而ConcurrentHashMap却不可以。
hashmap正确使用场景是单线程下,
由于是单线程,当得到的value是null的时候,可以用hashMap.containsKey(key)方法来区分上面说的两重含义(保证在单线程下 线程安全 不存在并发场景,所以不会存在二义性)。
但是如果是ConcurrentHashMap呢?
它的使用场景是多线程的情况下。假设concurrentHashMap允许存放值为null的value。
这时有A、B两个线程。
线程A调用concurrentHashMap.get(key)方法,返回为null,我们还是不知道这个null是没有映射的null还是存的值就是null。
我们假设此时返回为null的真实情况就是因为这个key没有在map里面映射过。那么我们可以用concurrentHashMap.containsKey(key)来验证我们的假设是否成立,我们期望的结果是返回false。
但是在我们调用concurrentHashMap.get(key)方法之后,containsKey方法之前,有一个线程B执行了concurrentHashMap.put(key,null)的操作。那么我们调用containsKey方法返回的就是true了。这就与我们的假设的真实情况不符合了。
总结:在map容器里面,调用map.get(key)方法得到的值是null,那你无法判断这个key是在map里面没有映射过,还是这个key在map里面根本就不存在。这种情况下,在非并发安全的map中,你可以通过map.contains(key)的方法来判断。但是在考虑并发安全的map中,在两次调用的过程中,这个值是有可能被改变的。