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