Java集合框架1HashMap

2017-04-05  本文已影响0人  paulpaullong

HashMap定义

package java.util;
import java.io.*;
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Serializable{
        static final Entry<?,?>[] EMPTY_TABLE = {}; // 空桶
        transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE; // 桶容器
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;  // 默认容量
        static final float DEFAULT_LOAD_FACTOR = 0.75f;  // 默认负载因子
       
        transient int modCount;
        // 其他成员变量和方法。。。
}

HashMap的数据结构

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;
}
// addEntry方法
public 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);
}

1)判断table是否为空,如果为空则扩充table,其中包括确保table的大小为2的整数倍。
2)如果key值为null,则特殊处理,调用putForNullKey(V value),hash值为0,存入table中,返回。
3)如果key值不为null,则计算key的hash值;
4)计算key在table中的索引index;
5)通过索引找到table[index]位置上的Entry“桶”,如果该桶为null,则直接进行增加操作;
6)如果该桶不为null,对其进行遍历,如果发现链表中有Entry的的key一致(hash和equals都一致),则用新值(value)替换旧值(oldValue),并保证key的唯一性;如果Entry“桶”内的所有key没有一个和传进来的key一致的,则进行增加操作。
7)增加操作前先判断是否需要扩容,然后将新加的Entry放到table数组中,之前在table数组中的Entry则被新加的Entry的next引用所指向。例如插入的顺序,原先table[index]的Entry链表是 old1->old2->old3,插入新值之后为new1->old1->old2->old3。

public V get(Object key) {   
    if (key == null) {
        return getForNullKey();
    }
   
    int hash = hash(key.hashCode()); 
  
    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.equals(k))) {
            return e.value;
        }
    }

    return null;   
}   

1)判断key值是否为null,如果是则特殊处理(在table[0]的链表中寻找)
2)否则计算hash值,进而获得table中的index值
3)在table[index]的链表中寻找,根据hash值和equals()方法获得相应的value。
4)如果找不到,最后返回null。

使用自定义的类的对象作为键

HashMap中的序列化问题

上一篇下一篇

猜你喜欢

热点阅读