HashMap、HashTable 和 ConcurrentHashMap 的键值对<K,V>能否为null
来源:互联网 发布:dijkstra算法c语言 编辑:程序博客网 时间:2024/06/07 14:25
本文目录
- 本文目录
- 已有结论
- HashMap的put源码
- HashTable的put源码
- ConcurrentHashMap的put源码
已有结论
HashMap
可以允许插入null key
和null value
HashTable
和ConcurrentHashMap
都不可以插入null key
和null value
HashMap
的put
源码:
/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old value is replaced. */ public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
/** * Offloaded version of put for null keys */ private V putForNullKey(V value) { for (Entry<K,V> e = table[0]; e != null; e = e.next) { if (e.key == null) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(0, null, value, 0); return null; }
可以看到 null key
的情况,调用putForNullKey
方法, 可以看到null key 元素被放在了第0个位置了, 如果第0个位置为空——直接赋值第0个位置, 否则, 在第0个位置产生一个链表,addEntry(0, null, value, 0);
HashTable
的put
源码:
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = hash(key); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { V old = e.value; e.value = value; return old; } } modCount++; if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; hash = hash(key); index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. Entry<K,V> e = tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; return null; }
源码中判断了null value
的情况,null value
就抛出空指针异常异常
但是我们并没有看到判断null key
然后抛出异常的语句,那么继续看看hash方法
的源码就明白了:
private int hash(Object k) { // hashSeed will be zero if alternative hashing is disabled. return hashSeed ^ k.hashCode(); }
k.hashCode()
,当k出入为null key
就会报错 空指针异常。
ConcurrentHashMap
的put
源码:
public V put(K key, V value) { Segment<K,V> s; if (value == null) throw new NullPointerException(); int hash = hash(key); int j = (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment s = ensureSegment(j); return s.put(key, hash, value, false); }
null value
和null key
会报错的问题和HashTable
原因是一样的,hash
方法:
private int hash(Object k) { int h = hashSeed; if ((0 != h) && (k instanceof String)) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); // Spread bits to regularize both segment and index locations, // using variant of single-word Wang/Jenkins hash. h += (h << 15) ^ 0xffffcd7d; h ^= (h >>> 10); h += (h << 3); h ^= (h >>> 6); h += (h << 2) + (h << 14); return h ^ (h >>> 16); }
阅读全文
0 0
- HashMap、HashTable 和 ConcurrentHashMap 的键值对<K,V>能否为null
- HashMap,LinkedHashMap,TreeMap,HashTable,ConcurrentHashMap,ConcurrentSkipListMap 关于k,v是否为null,以及输出排序
- hashtable,concurrenthashmap为什么键和值不能为null,而hashmap可以?
- HashMap HashTable和ConcurrentHashMap
- HashTable和HashMap和ConcurrentHashMap的区别
- HashMap、HashTable的key和value是否可为null
- HashMap、HashTable的key和value是否可为null
- HashMap HashTable和ConcurrentHashMap的区别
- HashMap HashTable和ConcurrentHashMap的区别
- HashMap、HashTable和ConcurrentHashMap的区别
- HashMap和Hashtable以及ConcurrentHashMap的区别
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比较
- HashMap,HashTable和ConcurrentHashMap的区别
- HashMap HashTable ConcurrentHashMap key和value是否可以null的问题 源码分析
- HashMap HashTable ConcurrentHashMap key和value是否可以null的问题 源码分析
- HashMap和HashTable的区别,HashTable和ConcurrentHashMap的区别
- ConcurrentHashMap和HashMap和HashTable
- ConcurrentHashMap和HashMap和HashTable
- HDFS异常恢复调研报告
- 阿里巴巴2016研发工程师笔试题
- getMetrics()和getReaMetrics()的区别
- 使用python实现排序算法(Insertion Sort)
- netperf 测试
- HashMap、HashTable 和 ConcurrentHashMap 的键值对<K,V>能否为null
- DATASET与JSON互转
- 利用Object.prototype.toString.call(obj)判断数据类型
- Python 3从入门到精通16-常用函数
- Java--面向对象之封装
- 欢迎使用CSDN-markdown编辑器
- 用QT写了一个串口工具,run之后总是报这个,要重启电脑才可以
- -webkit-text-stroke
- Tomcat SSL 配置