1、LinkedHashMap是有序的,是HashMap的子类,保留了插入的顺序,帮助我们实现了有序的HashMap。
2、其维护一个双向的链表,重写了HashMap的实体类Entry,实现能够将HashMap的数据组成一个双向列表,其存储的结构还是数组+链表的形式。
3、LinkedHashMap能够做到按照插入顺序或者访问顺序进行迭代顺序。
4、修改Entry对象,Entry新增了其上一个元素before和下一个元素after的引用
5、根据链表中元素的顺序可以分为:按插入顺序的链表,和按访问顺序(调用get方法)的链表。默认是按插入顺序排序,如果指定按访问顺序排序,那么调用get方法后,会将这次访问的元素移至链表尾部,不断访问可以形成按访问顺序排序的链表
6、LinkedHashMap并未重写父类HashMap的put方法,只是重写了put方法里面的recordAccess、addEntry、createEntry等方法,添加了特有的双向链接列表
7、LinkedHashMap重写了父类HashMap的get方法,实际在调用父类getEntry()方法取得查找的元素后,再判断当排序模式accessOrder为true时,记录访问顺序,将最新访问的元素添加到双向链表的表头,并从原来的位置删除。由于的链表的增加、删除操作是常量级的,故并不会带来性能的损失。
8、这个虽然是访问元素,但是当设置以访问排序时,其仍然会先将元素从原本位置remove掉,然后在将该元素以新元素插入到链头,哪怕其新插入的位置还在原位置(所以如果以访问排序,其过程会涉及到删除数据和增添数据)。
LinkedHashMap源码:
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
{
内部Entry为:
/**
* LinkedHashMap 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();
}
}