LinkedHahMap
public LinkedHashMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
accessOrder = false;
}
可以根据构造函数看出,LinkedHashMap的初始容量和加载因子都与Hashmap相同
accessOrder为true时,按照读取顺序输出
accessOrder为false时,按照插入顺序输出,
默认accessOrder为false
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
在LinkedHahMap中将内部链节点改为了双向链节点.
LinkedHahMap最重要的是实现了Hashmap的几个模板方法
HashMap:
void afterNodeInsertion(boolean evict) { }
LinkedHahMap:
void afterNodeInsertion(boolean evict) { // possibly remove eldest
LinkedHashMap.Entry<K,V> first;
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
removeNode(hash(key), key, null, false, true);
}
}
每一次在插入新值后,查看头结点是否已经过期,若过期,则去掉头结点.
HashMap:
void afterNodeAccess(Node<K,V> p) { }
LinkedHahMap:
void afterNodeAccess(Node<K,V> e) { // move node to last
LinkedHashMap.Entry<K,V> last;
if (accessOrder && (last = tail) != e) {
LinkedHashMap.Entry<K,V> p =
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
p.after = null;
if (b == null)
head = a;
else
b.after = a;
if (a != null)
a.before = b;
else
last = b;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
在方法开头进行了判断,
if (accessOrder && (last = tail) != e)
若根据获取顺序排序,该方法将最近获取的节点放到了链的最后.
HashMap:
void afterNodeRemoval(Node<K,V> p) { }
LinkedHahMap:
void afterNodeRemoval(Node<K,V> e) { // unlink
LinkedHashMap.Entry<K,V> p =
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
p.before = p.after = null;
if (b == null)
head = a;
else
b.after = a;
if (a == null)
tail = b;
else
a.before = b;
}
在删除节点后,同时将该节点从LinkedHahMap中的双链表中删除.
综上所述,在LinkedHahMap中维护了一个头结点为head,尾结点为tail的双向链表来保证有序的hash.