HashMap HashTable ConcurrentHashMap key和value是否可以null的问题 源码分析

来源:互联网 发布:市场调研数据分析报告 编辑:程序博客网 时间:2024/05/15 11:54

我们都知道结论是:

HashMap可以允许插入null key和null value

HashTable和ConcurrentHashMap都不可以插入null key和null value

具体原因可以看下面的源码:

首先是HashMap的put源码:

 

[java] view plain copy
  1. public V put(K key, V value) {  
  2.        if (table == EMPTY_TABLE) {  
  3.            inflateTable(threshold);  
  4.        }  
  5.      if (key == null)  
  6.            return putForNullKey(value);  
  7.        int hash = hash(key);  
  8.        int i = indexFor(hash, table.length);  
  9.        for (Entry<K,V> e = table[i]; e != null; e = e.next) {  
  10.            Object k;  
  11.            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
  12.                V oldValue = e.value;  
  13.                e.value = value;  
  14.                e.recordAccess(this);  
  15.                return oldValue;  
  16.            }  
  17.        }  
  18.   
  19.        modCount++;  
  20.        addEntry(hash, key, value, i);  
  21.        return null;  
  22.    }  

null key的情况,调用putForNullKey方法,之前我在博客上已经写过关于HashMap插入null key后的具体执行过程和源码分析了。

下面是HashTable的源码:

[java] view plain copy
  1. public synchronized V put(K key, V value) {  
  2.        // Make sure the value is not null  
  3.       if (value == null) {  
  4.            throw new NullPointerException();  
  5.        }  
  6.   
  7.        // Makes sure the key is not already in the hashtable.  
  8.        Entry tab[] = table;  
  9.       int hash = hash(key);  
  10.        int index = (hash & 0x7FFFFFFF) % tab.length;  
  11.        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
  12.            if ((e.hash == hash) && e.key.equals(key)) {  
  13.                V old = e.value;  
  14.                e.value = value;  
  15.                return old;  
  16.            }  
  17.        }  
  18.   
  19.        modCount++;  
  20.        if (count >= threshold) {  
  21.            // Rehash the table if the threshold is exceeded  
  22.            rehash();  
  23.   
  24.            tab = table;  
  25.            hash = hash(key);  
  26.            index = (hash & 0x7FFFFFFF) % tab.length;  
  27.        }  
  28.   
  29.        // Creates the new entry.  
  30.        Entry<K,V> e = tab[index];  
  31.        tab[index] = new Entry<>(hash, key, value, e);  
  32.        count++;  
  33.        return null;  
  34.    }  

源码中判断了null value的情况,null value就抛出空指针异常异常

但是我们并没有看到判断null key然后抛出异常的语句,那么继续看看hash方法的源码就明白了:

[java] view plain copy
  1. private int hash(Object k) {  
  2.         // hashSeed will be zero if alternative hashing is disabled.  
  3.         return hashSeed ^ k.hashCode();  
  4.     }  

k.hashCode(),当k出入为null key 就会报错 空指针异常。

下面是ConcurrentHashMap的源码:

[java] view plain copy
  1. public V put(K key, V value) {  
  2.         Segment<K,V> s;  
  3.       if (value == null)  
  4.             throw new NullPointerException();  
  5.       int hash = hash(key);  
  6.         int j = (hash >>> segmentShift) & segmentMask;  
  7.         if ((s = (Segment<K,V>)UNSAFE.getObject          // nonvolatile; recheck  
  8.              (segments, (j << SSHIFT) + SBASE)) == null//  in ensureSegment  
  9.             s = ensureSegment(j);  
  10.         return s.put(key, hash, value, false);  
  11.     }  

null value和null key 会报错的问题和HashTable原因是一样的,hash方法:

[java] view plain copy
  1. private int hash(Object k) {  
  2.        int h = hashSeed;  
  3.   
  4.        if ((0 != h) && (k instanceof String)) {  
  5.            return sun.misc.Hashing.stringHash32((String) k);  
  6.        }  
  7.   
  8.        h ^= k.hashCode();  
  9.   
  10.        // Spread bits to regularize both segment and index locations,  
  11.        // using variant of single-word Wang/Jenkins hash.  
  12.        h += (h <<  15) ^ 0xffffcd7d;  
  13.        h ^= (h >>> 10);  
  14.        h += (h <<   3);  
  15.        h ^= (h >>>  6);  
  16.        h += (h <<   2) + (h << 14);  
  17.        return h ^ (h >>> 16);  
  18.    }  
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 oppo手机第二屏幕打不开怎么办 红米note3屏幕裂了怎么办 小米3屏幕烂了怎么办 苹果x屏幕触屏不灵怎么办 票买好了身份证丢了怎么办 广发信用卡身份证到期了怎么办 人在外地身份证丢了怎么办 人在国外身份证丢了怎么办 身份证丢了户口本不在怎么办 在北京身份证过期了怎么办 没社保卡怎么办厦门健康卡 扬州市民卡丢了怎么办 扬州市民卡坏了怎么办 重庆社保卡坏了怎么办 社保卡丢了看病怎么办 社保卡丢了买药怎么办 常州社保卡丢了怎么办 深圳社保卡掉了怎么办 上海医保卡丢了怎么办 户口转到西安后医保怎么办 上海医保卡掉了怎么办 上海医保本丢了怎么办? 新版医保卡丢了怎么办 武汉社保卡掉了怎么办 职工社保卡丢了怎么办 杭州社保卡丢了怎么办 农村医疗卡丢了怎么办 陕西省医保卡丢了怎么办 小孩社保卡掉了怎么办 社区医保本丢了怎么办 宝宝医保卡掉了怎么办 同煤医疗卡丢了怎么办 杭州医保卡丢了怎么办 新的医保卡丢了怎么办 二代医保卡丢了怎么办 老医保卡丢了怎么办 上海医保卡余额用完了怎么办 身份证丢了医疗报销怎么办 取公积金身份证丢了怎么办 身份证丢了怎么办就诊卡 人在外地怎么办农村社保卡