|
|
|
@ -1,9 +1,9 @@
|
|
|
|
|
HashMap 大家都清楚,底层是 数组 + (红黑树 / 链表),**元素是无序的**,而 LinkedHashMap 则比 HashMap 多了这一个功能,并且,LinkedHashMap 的有序可以按两种顺序排列,一种是按照插入的顺序,一种是按照访问的顺序(初始化LinkedHashMap对象时设置accessOrder参数为true),而其内部是靠 建立一个双向链表 来维护这个顺序的,在每次插入、删除后,都会调用一个函数来进行 双向链表的维护,这也是实现 LRU Cache 功能的基础。
|
|
|
|
|
HashMap 大家都清楚,底层是 数组 + (链表 / 红黑树),**元素是无序的**,而 LinkedHashMap 则比 HashMap 多了这一个功能,并且,LinkedHashMap 的有序可以按两种顺序排列,一种是按照插入的顺序,一种是按照访问的顺序(初始化LinkedHashMap对象时设置accessOrder参数为true),而其内部是靠 建立一个双向链表 来维护这个顺序的,在每次插入、删除后,都会调用一个函数来进行 双向链表的维护,这也是实现 LRU Cache 功能的基础。
|
|
|
|
|
|
|
|
|
|
先说几个比较重要的结论,大家可以根据这些结论从后面的源码解析中 得到证据。
|
|
|
|
|
1. LinkedHashMap 继承了 HashMap,所以和 HashMap 的底层数据结构是一样的,都是数组+链表+红黑树,扩容机制也一样;
|
|
|
|
|
2. LinkedHashMap 通过双向链表来维护数据的顺序;
|
|
|
|
|
3. LinkedHashMap 存储顺序与添加顺序默认是一样得,同时可以根据 accessOrder参数 来决定是否在访问时移动元素,以实现 LRU 功能。
|
|
|
|
|
2. LinkedHashMap 是通过双向链表来维护数据的,与 HashMap 的拉链式存储不一样;
|
|
|
|
|
3. LinkedHashMap 存储顺序与添加顺序是一样得,同时可以根据 accessOrder参数 来决定是否在访问时移动元素,以实现 LRU 功能。
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
|
|
|
|
@ -120,6 +120,10 @@ public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
|
|
|
|
|
removeNode(hash(key), key, null, false, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 是否删除 最近最少使用的元素
|
|
|
|
|
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在访问元素之后,将该元素放到双向链表的尾巴处
|
|
|
|
|
void afterNodeAccess(Node<K,V> e) { // move node to last
|
|
|
|
@ -215,7 +219,7 @@ public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritDoc}
|
|
|
|
|
* 根据 key 获取对应的 value,如果key不存在,则返回给定的默认值 defaultValue
|
|
|
|
|
*/
|
|
|
|
|
public V getOrDefault(Object key, V defaultValue) {
|
|
|
|
|
Node<K,V> e;
|
|
|
|
|