HashMap之put 操作

key值为空的情况:
进行putForNull操作:
1.判断key值为null的Entry是否需存在,如果存在则将老值替换成新值(oldValue=newValue,返回老值),如果不存在的话,就addEntry(0,null,value,0)
2.addEntry(int hash, K key, V value, int bucketIndex)
在添加新的Entry的时候,Entry.key的hash计算出的位置如果有Entry元素的时候,将元素加入到该链表的头部,先进入的放到链表的尾部
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
//加入该项到链表头部
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}

    3.扩容首先要判断老的Map的长度是否大于等于最大的长度(1<<30,左移30位)

如果大于等于 ,threshold(判断是否扩容的条件即table.size>threshold),扩容位之前的两倍(threshold=DEFAULT_INITAL_CAPACITYDEFAULT_LOAD_FACTOR )=>160.75;如果到达最大容量,threshold=MAX_VALUE;如果没有超过则将长度扩大为之前的两倍,创建新的Entry数组,将新的数据transfer到新的Entry数组中,再将新的Entry数组赋值给老的Entry数组,此时将threshold=扩容后的Entry数组的长度* 加载因子

   void resize(int newCapacity) {
    Entry[] oldTable = table;
    int oldCapacity = oldTable.length;
    if (oldCapacity == MAXIMUM_CAPACITY) {
        threshold = Integer.MAX_VALUE;
        return;
    }
    Entry[] newTable = new Entry[newCapacity];
   ** transfer(newTable);**
    table = newTable;
    threshold = (int)(newCapacity * loadFactor);
}

4.transfer 将原数组中的数据传输到新的数组中
遍历 Entry 数组,遍历每个列下面的链表
 void transfer(Entry[] newTable) {
    Entry[] src = table;
    int newCapacity = newTable.length;
    for (int j = 0; j < src.length; j++) {
        Entry<K,V> e = src[j];
        if (e != null) {
            src[j] = null;
            do {
                Entry<K,V> next = e.next;
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
                e = next;
            } while (e != null);
        }
    }

猜你喜欢

转载自blog.51cto.com/13919712/2164882
今日推荐