HashMap解惑

2023-06-25,,

HashMap中有一些我们容易忽视的点,

Java代码  

  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.     }  

 由上述代码知道,hash值是用来确定bucketIndex,equals是用来和链表上的值比较,因此对于key是自定义的类,强烈建议重写hashCode和equals方法。

 再看如下代码下载

Java代码  

  1. void addEntry(int hash, K key, V value, int bucketIndex) {  

  2.         if ((size >= threshold) && (null != table[bucketIndex])) {  

  3.             resize(2 * table.length);  

  4.             hash = (null != key) ? hash(key) : 0;  

  5.             bucketIndex = indexFor(hash, table.length);  

  6.         }  

  7.   

  8.         createEntry(hash, key, value, bucketIndex);  

  9.     }  

 if条件告诉我们rehash的条件要同时满足两个:map中元素个数不小于阀值即容量*负载因子,对应的bucketIndex处有元素。

 另外,如下代码作备忘,

Java代码  

  1. static int indexFor(int h, int length) {  

  2.         // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";  

  3.         return h & (length-1);  

  4.     }  

《HashMap解惑.doc》

下载本文的Word格式文档,以方便收藏与打印。