HashMap底層原理分析(put、get方法)


 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM