1.非线程安全,可null键null值
2.无参构造默认大小16数组,负载因子0.75,扩容边界值16*0.75(阈值)
3.有参的构造函数,默认数组大小为大于或等于参数的最小的2的次幂,是为了元素分布均匀,数组每次扩容都是2倍扩容
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
4.indexfor函数,对数组索引的判断。在length为2的次幂时,可以使h按位与length-1时,哈希碰撞减少,从而减少查询时的链表遍历,提高查询效率。
static int indexFor(int h, int length) {
return h & (length-1);
}
5.扩容时要进行旧数组元素复制到新的2倍长度的新数组中,产生性能消耗,所以尽量设置默认大小,并且该大小要考虑负载因子。
6.遍历思路
第一个是获取keySet,遍历keySet针对每个key获取value
第二个是获取entrySet,遍历entrySet获取每个key和value
7.put过程
public V put(K key, V value) {
// 如果key为null使用putForNullKey来获取
if (key == null)
return putForNullKey(value);
// 使用hash函数预处理hashCode
int hash = hash(key.hashCode());
// 获取对应的索引
int i = indexFor(hash, table.length);
// 得到对应的hash值的桶,如果这个桶不是,就通过next获取下一个桶
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// 如果hash相同并且key相同
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
// 获取当前的value
V oldValue = e.value;
// 将要存储的value存进去
e.value = value;
e.recordAccess(this);
// 返回旧的value
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
8.addEntry
void addEntry(int hash, K key, V value, int bucketIndex) {
// 保存对应table的值
Entry<K,V> e = table[bucketIndex];
// 然后用新的桶套住旧的桶,链表
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
// 如果当前size大于等于阈值
if (size++ >= threshold)
// 调整容量
resize(2 * table.length);
}
9.resize
void resize(int newCapacity) {
// 保存oldTable
Entry[] oldTable = table;
// 保存旧的容量
int oldCapacity = oldTable.length;
// 如果旧的容量已经是系统默认最大容量了,那么将阈值设置成整形的最大值,退出
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
// 根据新的容量新建一个table
Entry[] newTable = new Entry[newCapacity];
// 将table转换成newTable
transfer(newTable);
// 将table设置newTable
table = newTable;
// 设置阈值
threshold = (int)(newCapacity * loadFactor);
}
10.transfer
void transfer(Entry[] newTable) {
// 得到旧的table
Entry[] src = table;
// 得到新的容量
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<K,V> e = src[j];
// 如果e不为空
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);
}
}
}
参考:http://blog.youkuaiyun.com/chenssy/article/details/18323767