IdentityHashMap

600 阅读1分钟

1. IdentityHashMap概述

IdentityHashMap是一致性哈希表,使用引用相等,而不是equals方法来比较两个对象的相等性。因此, IdentityHashMap使用System.identityHashCode来确定对象的哈希码,该方法返回对象的地址。 看下IdentityHashMap的存储原理图,和HashMap不同,HashMap是通过数组+拉链法存储元素并解决哈希冲突的。IdentityHashMap将所有的key和value都存储到Object[]数组table中,并且key和value相邻存储,当出现哈希冲突时,会往下遍历数组,直到找到一个空闲的位置。注意,数组第一个位置存储的是key,第二个位置存储的是value。因此奇数位置处存储的是key,偶数位置处存储的是value。

图片.png

2. IdentityHashMap put 源码 jdk1.8

public V put(K key, V value) 
{
    final Object k = maskNull(key);

    retryAfterResize: for (;;) {
        final Object[] tab = table;
        final int len = tab.length;
        int i = hash(k, len);

        for (Object item; (item = tab[i]) != null;
             i = nextKeyIndex(i, len)) {
             // 用的== 不是equals
            if (item == k) {
                @SuppressWarnings("unchecked")
                    V oldValue = (V) tab[i + 1];
                tab[i + 1] = value;
                return oldValue;
            }
        }

        final int s = size + 1;
        // Use optimized form of 3 * s.
        // Next capacity is len, 2 * current capacity.
        if (s + (s << 1) > len && resize(len))
            continue retryAfterResize;

        modCount++;
        tab[i] = k;
        tab[i + 1] = value;
        size = s;
        return null;
    }
}

3. IdentityHashMap get 源码 jdk1.8

public V get(Object key) {
    Object k = maskNull(key);
    Object[] tab = table;
    int len = tab.length;
    int i = hash(k, len);
    while (true) {
        Object item = tab[i];
        if (item == k)
            return (V) tab[i + 1];
        if (item == null)
            return null;
        i = nextKeyIndex(i, len);
    }
}