-
map.put 方法解析
// map.put 方法 不能存null的key和value // 不成立:map.put(null, null) map.put(null,Object) map.put(Object, null) // map.put 在這裏沒有如果put不滿足的數值 會拋出異常 java.lang.NullPointerException public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) {// key也不能爲null 可以爲字符串: "",字符串""的 hash 爲0 throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table;//定義tab[] int hash = key.hashCode();//取key的hash值 int index = (hash & 0x7FFFFFFF) % tab.length;//取模運算 計算需要存儲的位置 @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; //確定當前位置是否已存在數據,hash存儲會有數據碰撞的機率,這就是爲什麼說兩個對象的 // hashcode相等,值卻不一定相等的原因,例如: Aa 和 BB 的hashCode 都是2112 //循環判斷當前需要存儲的位置的entry是否爲已存儲的數據,hash表存儲數據格式(數組與鏈表存儲 //的結合) 成立則覆蓋oldValue並返回old 不成立則繼續循環下一個 for(; entry != null ; entry = entry.next) { // 判斷是否是重複key數據put if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index);//執行newEntry的add操作 return null; } // addEntry方法解析 執行數組的擴容操作以及add操作 private void addEntry(int hash, K key, V value, int index) { modCount++; Entry<?,?> tab[] = table;//定義tab[] //判斷當前的存儲數量是否超出或等於當前數組最大的容量閥值 if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash();//執行擴容的方法 oldCP * 2 + 1 tab = table;//擴容之後的newTable hash = key.hashCode(); index = (hash & 0x7FFFFFFF) % tab.length;//取模計算需要存放的位置 } // Creates the new entry. @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>) tab[index];// 取當前位置是否存在oldEntry //執行Entry的鏈表存儲結構先入的放到後面 //protected Entry(int hash, K key, V value, Entry<K,V> next) { //this.hash = hash; //this.key = key; //this.value = value; //this.next = next; //} tab[index] = new Entry<>(hash, key, value, e); count++; } // rehash() 方法 執行數組的擴容方法 oldCp * 2 + 1 @SuppressWarnings("unchecked") protected void rehash() { int oldCapacity = table.length;//定義oldCp Entry<?,?>[] oldMap = table;// 定義 oldMap 執行copy時使用 執行擴容之後的數組爲table // overflow-conscious code int newCapacity = (oldCapacity << 1) + 1;// newCp 爲 oldCp * 2 + 1 if (newCapacity - MAX_ARRAY_SIZE > 0) {// HashTable 的最大容量是MAX_ARRAY_SIZE if (oldCapacity == MAX_ARRAY_SIZE) // Keep running with MAX_ARRAY_SIZE buckets return; newCapacity = MAX_ARRAY_SIZE;// 定義newCp 爲MAX_ARRAY_SIZE } Entry<?,?>[] newMap = new Entry<?,?>[newCapacity]; modCount++; // 最大容量閥值爲 newCp * 0.75(默認) 或者 MAX_ARRAY_SIZE + 1 threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1); table = newMap;// 從新定義table 執行copy操作 for (int i = oldCapacity ; i-- > 0 ;) {// 循環執行數據的copy // 執行 散列表數據結構的 copy for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) { Entry<K,V> e = old;// 將oldEntry 賦值 給e old = old.next;// 從新定義oldEntry 爲old.next int index = (e.hash & 0x7FFFFFFF) % newCapacity;// 取模計算新數組的存放位置 e.next = (Entry<K,V>)newMap[index];//防止數據丟失 鏈表存儲結構 先入後出 newMap[index] = e;// 執行數據的存放 } } }
-
map.get(key) 方法解析
// map.get() 方法源碼解析 @SuppressWarnings("unchecked") public synchronized V get(Object key) { Entry<?,?> tab[] = table;// 定義tab[] int hash = key.hashCode();//取key的hashCode int index = (hash & 0x7FFFFFFF) % tab.length;//與運算 取模計算存儲的位置 for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {// 循環對比取值 if ((e.hash == hash) && e.key.equals(key)) {// 判斷是否匹配 return (V)e.value;//成功返回value } } return null;//無匹配數據返回null }
-
map.putAll(Map<? extends K, ? extends V> m) 方法解析
// map.putAll() 方法源碼解析 // 循環執行map數據的put操作 public synchronized void putAll(Map<? extends K, ? extends V> t) { for (Map.Entry<? extends K, ? extends V> e : t.entrySet()) put(e.getKey(), e.getValue());// put源碼 }
-
map.remove(key) 方法解析
// map.remove(Object key) 方法源碼解析 // remove 的方法 是先執行get(key) 方法 在執行數據的remove public synchronized V remove(Object key) { Entry<?,?> tab[] = table;//定義tab[] int hash = key.hashCode();//去key的hashCode int index = (hash & 0x7FFFFFFF) % tab.length;//與運算 取模 計算數據的存儲位置 @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>)tab[index];// 找到需要remove的鏈表數據結構對象 //循環對比 找到需要remove的對象 for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) { if ((e.hash == hash) && e.key.equals(key)) {//判斷條件是否成立 modCount++; if (prev != null) {//如果prev != null 鏈表數據結構remove 只需要移動指針操作 prev.next = e.next; } else { tab[index] = e.next;//當前鏈表的first位置,移動指針操作 } count--; V oldValue = e.value; e.value = null;// 設置爲null 方便回收 return oldValue;//返回remove的value值 } } return null;// 不匹配返回null }
Map的實現類Hashtable各種方法源碼解析
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.