1、HashMap底層原理分析(put、get方法)
HashMap底層是通過數組加鏈表的結構來實現的。HashMap通過計算key的hashCode來計算hash值,只要hashCode一樣,那hash值就是相同的。當hash值相同時,就會出現hash沖突,HashMap通過鏈表來解決沖突。
原理圖:
實例:
import java.util.HashMap; import java.util.Map; public class HashMapTest { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("fruit", "apple"); System.out.println(map.get("fruit"));
1、put方法分析
//添加鍵值對方法 public V put(K key, V value) { //如果key為null,則hash值為0,將這個entry放在索引為0的地方,即table[0] if (key == null) return putForNullKey(value); //key不為null int hash = hash(key.hashCode());//計算key的hashCode的hash值 int i = indexFor(hash, table.length);//返回hash值所在的索引位置 //遍歷table[i]處的Entry,若存在key相同並且hash值相同,則用新元素替換舊元素 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; } } //修改標記+1,然后進行元素添加操作 modCount++; addEntry(hash, key, value, i);//將包含特定key、value和hash值的entry添加到特定的桶中 return null; } //添加key為null的元素 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; } /** * Adds a new entry with the specified key, value and hash code to * the specified bucket. It is the responsibility of this * method to resize the table if appropriate. * * Subclass overrides this to alter the behavior of put method. */ void addEntry(int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<>(hash, key, value, e); if (size++ >= threshold) resize(2 * table.length); }
2、get方法分析
/** * 返回映射的key對應的value值,若map不包含該key,返回null */ public V get(Object key) { if (key == null)//獲取key為null的value值 return getForNullKey(); int hash = hash(key.hashCode());//計算key的hashCode的hash值 //遍歷數組中對應hash值的Entry鏈表,若Entry元素的hash值與hashCode的hash值相等並且key與查找的key相等,則返回此Entry元素的value值 for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }