HashMap使用哈希表来存储数据,并用拉链法来处理冲突。
1. 关于容量的问题,使用2的幂方
如果给定Map一个初始容量,但看构造器里,会寻找比这个初始值大的2的幂方
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
所以在寻找Hash位置的时候,可以直接利用位运算。
// Returns index for hash code h.
static int More ...indexFor(int h, int length) {
return h & (length-1);
}
私有类class Entry<K,V> extends HashMap.Entry<K,V>
// 这是一个私有的、静态的内部类,继承自HashMap的Entry。
private static class Entry<K,V> extends HashMap.Entry<K,V> {
// 对前后节点的引用
Entry<K,V> before, after;
// 构造方法直接调用父类的构造方法
Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
super(hash, key, value, next);
}
// 移除该节点,只需修改前一节点的after引用和后一节点的before引用
private void remove() {
// 修改后该节点服务再被访问,会被GC回收
before.after = after;
after.before = before;
}
// 在指定节点之前插入当前节点(双向链表插入节点的过程)
private void addBefore(Entry<K,V> existingEntry) {
// 将当前节点的after引用指向existingEntry
after = existingEntry;
// 将before的引用指向existingEntry节点的前一节点
before = existingEntry.before;
// 将原先existingEntry节点的前一节点的after引用指向当前节点
before.after = this;
// 将原先existingEntry节点的后一节点的before引用指向当前节点
after.before = this;
}
//remove();加addBefore(lm.header);可以将元素移动到header之前
//
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
// 和recordAccess(HashMap<K.V> m)方法一样,在HashMap.Entry中同样有一个对应的空方法。当进行删除(remove)操作的时候会被调用
void recordRemoval(HashMap<K,V> m) {
remove();
}
}
int expectedModCount; // For fast-fail
http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html