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;
            }
        }
       //不存在key相同hash值相同的元素,修改标记+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;
    }

猜你喜欢

转载自www.cnblogs.com/stm32stm32/p/9035519.html