建议先看HahsMap的源码:
https://blog.youkuaiyun.com/superprintf/article/details/123874360
LinkedHashMap使用HashMap的模板方法设计模式。HashMap我们清楚,那LinkedList就是按照插入结点的顺序维护一个双向链表。最终达到可以循环访问的效果

一些变量
head是最老的,tail是最年轻的

accessOrder 对访问命令为真,插入命令为false

get方法
调用HashMap中的getNode查找结点。accessOrder为True时,也就是访问模式,执行afterNodeAccess,把访问的元素插入到队尾


可上面modeCount是有关并发控制的东西。
这个afterNodeAccess是LinkedHashMap重写HashMap接口,HashMap中经常使用这个方法。
HashMap中的接口

getOrDefault就很好理解了

modCount
经常能看到这个东西,并发执行的时候会同时修改modeCount导致数量和原先的值对不上,所以会抛出异常ConcurrentModificationException
int mc = modCount;
//执行操作
.......
if (modCount != mc)
throw new ConcurrentModificationException();
newNode
新建结点的时候会插入到队尾


但是要注意LinkedHashMap是重写了HashMap中的newNode方法

在调用hasmap中put方法的时候会使用自己重写的newNode方法

removeEldestEntry
在插入Node结点之后会判断是否需要移除最久未使用结点,通过removeEldestEntry方法

protected方法,可自定义从而实现LRU

afterNodeInsertion方法,也是重写了HashMap中的接口

HashMap中比如说put方法,他最后就会调用这个方法

总结下
LinkedHashMap是在HashMap的基础上维护一个双向链表,是通过重写HashMap中提供的接口注入到HashMap中的方法
比如重写newNode方法,实现了队尾插入逻辑
比如重写afterNodeRemoval方法,实现了修改双向指针的逻辑
而LinkedHashMap自身实现的比较重要的逻辑是removeEldestEntry,我们可以通过实现自己的逻辑来删除最久未使用元素,比如当当前的size大于总的capacity的时候就进行队尾删除。
this.cache = new LinkedHashMap<Integer,Integer>(capacity, 0.75f, true){
@Override
protected boolean removeEldestEntry(Map.Entry eldest){
return cache.size() > capacity;
}
}
本文深入探讨了LinkedHashMap,它是HashMap的一个子类,通过维护一个双向链表实现有序性。LinkedHashMap在插入和访问节点时有特定的行为:访问时,如果accessOrder为true,节点会被移动到链表尾部。newNode方法用于在链表尾部插入新节点,而removeEldestEntry则允许自定义策略移除最旧的条目,如达到容量限制时。通过对HashMap接口的重写,LinkedHashMap实现了LRU(最近最少使用)缓存策略等功能。
689

被折叠的 条评论
为什么被折叠?



