JDK源码之解读hashMap 的put和get方法的实现原理

JDK源码之解读hashMap 的put和get方法的实现原理

1,put
             对于方法hashmap.put(K,V),首先是把k处理,通过hashcode方法处理得到K对应的hash=hash(K).
             再调用h & (length-1)得到数组下标i. 最后调用createEntry(hash, key, value, i)方法,把hash,key,value存入table[i]一维数组中。源码如下:
             
 public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        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;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
 final int hash(Object k) {
        int h = 0;
        if (useAltHashing) {
            if (k instanceof String) {
                return sun.misc.Hashing.stringHash32((String) k);
            }
            h = hashSeed;
        }


        h ^= k.hashCode();


        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
 void addEntry(int hash, K key, V value, int bucketIndex) {
        if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }


        createEntry(hash, key, value, bucketIndex);
    }
总结就是说,先用键生成hashcode,然后把键和值存入一个对象为键值对的一维数组中,位置是,按生成hashcode转变得到的数字作为一维数组的下标。
有人会说,万一生成的hashcode一样咋办?=== 因为他是把键值对存入一维数组中,键是唯一的,所以hashcode一样时候,根据对象里面的键不同,一样可以取出唯一对应的值。

2,get
           弄懂put方法原理,这个就很简单了。根据对应的键,找到hashcode,去一维数组根据hashcode生成的下标去取对应的值,
           如果hashcode一样,根据唯一键在一位数组里面取值。源码如下:
          
  public V get(Object key) {
        if (key == null)
            return getForNullKey();
        Entry<K,V> entry = getEntry(key);

        return null == entry ? null : entry.getValue();
    }
  final Entry<K,V> getEntry(Object key) {
        int hash = (key == null) ? 0 : hash(key);
        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 != null && key.equals(k))))
                return e;
        }
        return null;
    }

阅读更多

没有更多推荐了,返回首页