浅析HashMap源码

HashMap 中 put 操作,添加元素的源码如下:

/**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with key, or
     *         null if there was no mapping for key.
     *         (A null return can also indicate that the map
     *         previously associated null with key.)
     */
    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry 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;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

其实关于源码解析已经看过几遍,但是今天再次拾起的时候发现了之前不曾注意到的,关于HashMap中添加

元素的操作,table数组是其用来记录元素的数组,数组存储Entry元素类型,本质上为一个哈希链地址表。

第一个操作是去判断这个表是否已经添加元素,如果表为空,说明还没有添加任何元素,对table进行初始化操作。

如果key为空,则直接进行插入操作,因为null键值位于table表的第一个元素位置,所以直接进行插入。

重点看下红色字体的for部分。HashMap先计算出元素的哈希码,通过这个哈希码来寻找目标元素的地址。

hash(key)为求哈希码操作,indexFor操作为确定目标元素在table中的位置。接下来for中要做的就是遍历这

个链接表,这里采用的是顺序搜索的方式。如果哈希码和key都一样,则进行替换操作,否则采用头插法插入元素。为什么要使用链地址法进行操作,因为计算哈希码的时候可能发生冲突,使用链地址法把具有相同哈希码的元素

都存储在一块。这个操作今天才想明白。

你可能感兴趣的:(java)