LinkedHashMap 继承了HashMap<K,V> 实现了 Map<K,V>接口
在LinkedHashMap中定义了新的Entry结构,它继承了 HashMap.Entry<K,V>. 定义了两个成员变量Entry<K,V> before, after;用于存储前面entry和后面entry的应用。实现双向链表的结构
在LinkedHashMap中定义了一个成员变量来实现双向链表的头节点
覆盖了父类的addEntry方法。通过e.addBefore(header);将变量加到链表中
遍历双向链表实现查找
LinkedHashMap支持两种排序:插入顺序、访问顺序
插入顺序访问,当accessOrder == true时,会把最近访问过的值放到链表的最后,可以实现按访问顺序排序。否则就是按照插入顺序排序
总结:实现了双向链表查询。并且支持插入顺序、访问顺序两种排序方式。
在LinkedHashMap中定义了新的Entry结构,它继承了 HashMap.Entry<K,V>. 定义了两个成员变量Entry<K,V> before, after;用于存储前面entry和后面entry的应用。实现双向链表的结构
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中定义了一个成员变量来实现双向链表的头节点
private transient Entry<K,V> header;
覆盖了父类的addEntry方法。通过e.addBefore(header);将变量加到链表中
void addEntry(int hash, K key, V value, int bucketIndex) {
createEntry(hash, key, value, bucketIndex);
// Remove eldest entry if instructed, else grow capacity if appropriate
Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
} else {
if (size >= threshold)
resize(2 * table.length);
}
}
/**
* This override differs from addEntry in that it doesn't resize the
* table or remove the eldest entry.
*/
void createEntry(int hash, K key, V value, int bucketIndex) {
HashMap.Entry<K,V> old = table[bucketIndex];
Entry<K,V> e = new Entry<K,V>(hash, key, value, old);
table[bucketIndex] = e;
e.addBefore(header);
size++;
}
遍历双向链表实现查找
public boolean containsValue(Object value) {
// Overridden to take advantage of faster iterator
if (value==null) {
for (Entry e = header.after; e != header; e = e.after)
if (e.value==null)
return true;
} else {
for (Entry e = header.after; e != header; e = e.after)
if (value.equals(e.value))
return true;
}
return false;
}
LinkedHashMap支持两种排序:插入顺序、访问顺序
插入顺序访问,当accessOrder == true时,会把最近访问过的值放到链表的最后,可以实现按访问顺序排序。否则就是按照插入顺序排序
public V get(Object key) {
Entry<K,V> e = (Entry<K,V>)getEntry(key);
if (e == null)
return null;
e.recordAccess(this);
return e.value;
}
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
总结:实现了双向链表查询。并且支持插入顺序、访问顺序两种排序方式。