LinkedHashMap的定义
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
{
private transient Entry<K,V> header;//头结点
private final boolean accessOrder;//为false时按插入顺序排序,根据构造方法来看基本上都是调用hashMap的构造方法,accessOrder都为false,默认插入顺序排序
根据下面的Entry的定义 画出LinkedHashMap的数据结构
private static class Entry<K,V> extends HashMap.Entry<K,V> {
// These fields comprise the doubly linked list used for iteration.
Entry<K,V> before, after;Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
super(hash, key, value, next);
}/**
* Removes this entry from the linked list.
*/
private void remove() {
before.after = after;
after.before = before;
}/**
* Inserts this entry before the specified existing entry in the list.
*/
private void addBefore(Entry<K,V> existingEntry) {
after = existingEntry;
before = existingEntry.before;
before.after = this;
after.before = this;
}/**
* This method is invoked by the superclass whenever the value
* of a pre-existing entry is read by Map.get or modified by Map.set.
* If the enclosing Map is access-ordered, it moves the entry
* to the end of the list; otherwise, it does nothing.
*/
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}void recordRemoval(HashMap<K,V> m) {
remove();
}
}
LinkedHashMap,重写了addEntry方法和creatEntry方法,
void addEntry(int hash, K key, V value, int bucketIndex) {
super.addEntry(hash, key, value, bucketIndex);// Remove eldest entry if instructed
Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}
}void createEntry(int hash, K key, V value, int bucketIndex) {
HashMap.Entry<K,V> old = table[bucketIndex];
Entry<K,V> e = new Entry<>(hash, key, value, old);
table[bucketIndex] = e;
e.addBefore(header);
size++;
}
HashMap遍历时,按哈希表的每一个索引的链表从上往下遍历,由于HashMap的存储规则,最晚添加的节点都有可能在第一个索引的链表中,这就造成了HashMap的遍历时无序的,而linkedhashMap是从头结点遍历的
private abstract class LinkedHashIterator<T> implements Iterator<T> {
Entry<K,V> nextEntry = header.after;//nextEntry指向头结点的下一个节点,也就是双向链表中的第一个节点
Entry<K,V> lastReturned = null;/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;public boolean hasNext() {
return nextEntry != header;
}public void remove() {
if (lastReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();LinkedHashMap.this.remove(lastReturned.key);
lastReturned = null;
expectedModCount = modCount;
}Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (nextEntry == header)
throw new NoSuchElementException();Entry<K,V> e = lastReturned = nextEntry;
nextEntry = e.after;
return e;
}
}