每日读源码(4)

作者: JUNE言JUNE语 | 来源:发表于2016-12-03 22:23 被阅读18次

    又到了每天读一读源代码的时候啦。今天来看看HashMap

    其实原本是想先写HashSet的,不过后来看到HashSet底层是用HashMap实现的,所以就先写HashMap

    首先讲一下Map吧,Map是以key-value存储的数据结构,key可以看成是value的索引,作为key的对象集合是不能重复的。

        /**
         * The default initial capacity - MUST be a power of two.
         */
        static final int DEFAULT_INITIAL_CAPACITY = 16;
    

    HashMap的默认容量大小是16(记住ArrayList是10)

    HashMap设置了一个阈值threshold=capacity * load factor
    这也是loadFactor存在的意义,就是当Map的size占容量的比例等于loadFactor时,就会触发扩容。

    先讲一下HashMap的put函数吧
        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;
        }
    

    先通过key计算对应的hash值,
    然后通过indexFor方法获取对应存储的数组位置
    接下去一个for循环,通过拉链法存储。
    if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
    先判断两个key的hash值是否相同,如果不同则直接跳过
    如果相同再判断两个key是否==或者equals。
    如果出现相同那么就将对应的value替换。

    再讲一个比较正常的方法,get
        public V get(Object key) {
            if (key == null)
                return getForNullKey();
            Entry<K,V> entry = getEntry(key);
    
            return null == entry ? null : entry.getValue();
        }
    

    简单看一下,大概就是通过key获取对应的Entry,然后通过Entry获取对应的value。

    今天就先到这里,累死咯。。

    每天看一点源代码,幸福生活每一天。

    相关文章

      网友评论

        本文标题:每日读源码(4)

        本文链接:https://www.haomeiwen.com/subject/nwicmttx.html