每日读源码(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