public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { //默认的初始容量(初始数组的长度)是16,且必须是2的整数次幂, static final int DEFAULT_INITIAL_CAPACITY = 16; //数组的长度范围是[0,2的30次方], 小于0会抛异常,大于MAXIMUM_CAPACITY会被它覆盖。 static final int MAXIMUM_CAPACITY = 1 << 30; //默认的加载因子 static final float DEFAULT_LOAD_FACTOR = 0.75f; //存放数据的Entry数组,实际容量必须是2的幂 //每个Entry元素其实是一个链表 transient Entry[] table; //HashMap中已经存放数据的个数,并非一定是数组的长度 transient int size; //HashMap的阈值,如果size>threshold(threshold = 容量 * 加载因子)则HashMap需要rehash int threshold; //加载因子 final float loadFactor; //HashMap被改变的次数 transient volatile int modCount; }
static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; final int hash; /** * 创建新的Entry,并让其next指针指向n */ Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; key = k; hash = h; } //获得key public final K getKey() { return key; } //获得value public final V getValue() { return value; } //设置value,并返回原来得value public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } //比较两个Entry是否相等 //首先,判断其key是否相等,然后再判断value是否相等, //只有key和value都相等,两个entry才相等 public final boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; Object k1 = getKey(); Object k2 = e.getKey(); if (k1 == k2 || (k1 != null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) return true; } return false; } //计算哈希值 public final int hashCode() { return (key==null ? 0 : key.hashCode()) ^ (value==null ? 0 : value.hashCode()); } public final String toString() { return getKey() + "=" + getValue(); } //没做任何事情 void recordAccess(HashMap<K,V> m) { } //没做任何事情 void recordRemoval(HashMap<K,V> m) { } }
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); 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 V putForNullKey(V value) { for (Entry<K,V> e = table[0]; e != null; e = e.next) { if (e.key == null) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(0, null, value, 0); return null; }
//求hash值的方法,重新计算hash值 static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } // 返回h在数组中的索引值,这里用&代替取模,旨在提升效率 static int indexFor(int h, int length) { return h & (length-1); }
h |
length – 1 |
二进制 |
h&length-1 |
0(0000) |
1111 |
0000 |
0 |
1(0001) |
1111 |
0001 |
1 |
12(1100) |
1111 |
1100 |
12 |
16(10000) |
1111 |
0000 |
0 |
20(10100) |
1111 |
0100 |
4 |
//添加新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) //如果size>阈值,则将数组长度扩大成原来的两倍 resize(2 * table.length); } //调整大小 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); } //转移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); } } }
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; } private V getForNullKey() { for (Entry<K,V> e = table[0]; e != null; e = e.next) { if (e.key == null) return e.value; } return null; }1、首先判断key是否为null,如果是则遍历以table[0]为头节点的链表,如果e.key==null,则返回其value;
原文地址:http://blog.csdn.net/zhangzz1127/article/details/39105247