1. 程式人生 > >HashMap源代碼解析

HashMap源代碼解析

new imu 感覺 sna 因子和 遍歷 會有 修改 color

  HashMap原理剖析

  之前有看過別人的HashMap源代碼的分析,今天嘗試自己來分析一波,純屬個人愚見。聽一些老的程序員說過,當別人跟你說用某樣技術到項目中去,而你按照別人的想法實現了的時候,你只能是一個碼農,當你自己會想到用一樣東西到你的實際開發中的時候,你是一個普通的程序員,當你不僅能想到用某樣技術到項目中去,而且深深的熟悉這項技術的底層實現,那就是一個有內功的程序員了。

  HashMap,哈希表,基於哈希算法實現的一個java集合。起初使用這個哈希表的時候,感覺非常的不習慣,主要是容易和其他的幾種哈希表搞混,就當時的理解來說,哪個哈希表的鍵不能為空,哪個哈希表的值可以為空等等,覺得這些東西記住了就感覺自己非常的牛逼了。但是隨著學習的進一步深入,總會有疑問,哈希表到底是如何實現的?那就按照api的方法來一個一個解釋。

構造方法:

1.空參數的構造方法

 1      public HashMap() {
 2             //初始化加載因子,等於默認的加載因子0.75
 3             this.loadFactor = DEFAULT_LOAD_FACTOR;
 4             //最大容量為初始化容量乘以加載因子
 5             threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
 6             //初始化一個長度為16的entry數組,也就是存放鍵值對的數組
 7
table = new Entry[DEFAULT_INITIAL_CAPACITY]; 8 //調用init方法 9 init(); 10 }

2.初始化容量的構造方法

1 public HashMap(int initialCapacity) {
2        //調用兩個參數的構造方法,初始化容量和默認加載因子
3        this(initialCapacity, DEFAULT_LOAD_FACTOR);
4 }

3.初始化容器和初始化加載因子的構造方法

public HashMap(int
initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); int capacity = 1; while (capacity < initialCapacity) capacity <<= 1; this.loadFactor = loadFactor; threshold = (int)(capacity * loadFactor); table = new Entry[capacity]; init(); }

4.Map集合作為參數的構造方法

1 public HashMap(Map<? extends K, ? extends V> m) {
2     //調用初始化加載因子和初始化容量兩個參數的構造方法
3     this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
4                DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
5     //將參數Map中的key-value對放入新創建的map集合中
6     putAllForCreate(m);
7}

存放鍵值對的方法:

 1 public V put(K key, V value) {
 2         //如果key為空,則調用放入null key的方法,占用entry數組的一個位置
 3         if (key == null)
 4             return putForNullKey(value);
 5         //根據key值計算出hash碼值
 6         int hash = hash(key.hashCode());
 7         //並根據哈希碼的值計算出該key-value在entry數組中的存放位置
 8         int i = indexFor(hash, table.length);
 9         //根據索引直接定位到那個元素並且從那個元素開始遍歷
10         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
11             Object k;
12             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
13                 V oldValue = e.value;
14                 e.value = value;
15                 e.recordAccess(this);
16                 return oldValue;
17             }
18         }
19     
20         modCount++;//修改次數加1
21         addEntry(hash, key, value, i);//將key-value對添加進入entry數組
22         return null;
23     }            

HashMap源代碼解析