码迷,mamicode.com
首页 > 其他好文 > 详细

HashMap源码解析

时间:2015-06-12 18:52:10      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:

  今天来看下HashMap源码,先从put方法入手:

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<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;
    }

第一部分主要完成对空容器的一个初始化:

private void inflateTable(int toSize) {
        // Find a power of 2 >= toSize
        int capacity = roundUpToPowerOf2(toSize);

        threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
        table = new Entry[capacity];
        initHashSeedAsNeeded(capacity);
    }

如果key为null时会将键值对插在table[0]这个位置,可见null可以作为HashMap的键值,

int hash = hash(key);
int i = indexFor(hash, table.length);

这两行主要是为了在table数组中定位,其中可以看出String的hash值只跟字符内容有关。

table数组的每个元素都是一个Entry<K,V>链表,

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;
            }
        }

这一段就是要验证插入前HashMap是否存在与插入元素相同的键值,如果有就更新值,如果没有

 addEntry(hash, key, value, i);
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);
    }

如果size超过threshold就扩容否则将新建元素插入都链表头部。

详细参考http://www.cnblogs.com/matrix-skygirl/archive/2013/01/17/2864919.html

HashMap源码解析

标签:

原文地址:http://www.cnblogs.com/yigeboke/p/4572018.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!