LinkedHashMap
LinkedHashMap是HashMap的一个子类,HashMap是无序的,LinkedHashMap遍历是有序的,下面来看看LinkedHashMap做了什么操作让遍历有序呢?
//LinkedHashMap.put()其实会调用HashMap put()
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
newNode()会调用子类LinkedHashMap的newNode()方法
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
LinkedHashMap.Entry<K,V> p =
new LinkedHashMap.Entry<K,V>(hash, key, value, e);
linkNodeLast(p);
return p;
}
// link at the end of list
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
LinkedHashMap.Entry<K,V> last = tail;
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
}
保证遍历有序的内幕就在linkNodeLast()方法,这里维护了一个双向链表,将插入的结点,依次保存在这
final boolean accessOrder;
if (accessOrder)
afterNodeAccess(e);
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;
}
}
将accessOrder设为true时,LinkedHashMap的get()操作,或put()的覆盖操作会原结点的位置移动到双向链表尾部