AfterNodeInsertion方法
在Hashmap中它与其他后处理方法都是空实现:
// Callbacks to allow LinkedHashMap post-actions
void afterNodeAccess(Node<K,V> p) { }
void afterNodeInsertion(boolean evict) { }
void afterNodeRemoval(Node<K,V> p) { }
在LinkedHashMap中实现如下(LinkedHashMap继承了Hashmap):
void afterNodeInsertion(boolean evict) { // possibly remove eldest
LinkedHashMap.Entry<K,V> first;
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
removeNode(hash(key), key, null, false, true);
}
}
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
在LinkedHashMap中这个方法removeEldestEntry永远返回false,如果为true走的是移除head节点的逻辑。head节点就是最开始插入map的节点,也可以称为最旧的节点。
所以可以知道if判断永远是false,所以什么逻辑也不走。
但是我们先记住if判断里的条件,下面有用
上面的remove返回false,可以看出这些后处理方法不是给LinkedHashMap类和HashMap类使用的。用于继承了LinkedHashMap类的类使用,例如LRUCache,这个类所有代码如下
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
protected int maxElements;
public LRUCache(int maxSize) {
super(maxSize, 0.75F, true);
this.maxElements = maxSize;
}
@Override
protected boolean removeEldestEntry(Entry<K, V> eldest) {
return (size() > this.maxElements);
}
}
在LRUCache中重写了这个方法,作用是当当前链表大小大于最大容量时,移除一个最旧的元素,因为removeEldestEntry方法返回true,而且HashMap的put方法最后会调用afterNodeInsertion(true);这个方法的if判断只会判断三个条件,
第一个是传入的evict参数true还是false,evict英文是驱逐的意思,
第二个是当前head节点不为空
第三个则就是removeEldestEntry方法返回的参数
因此当LRUCache put元素时,会在put元素后调用后处理方法AfterNodeInsertion,它内部if条件判断里再调用removeEldestEntry方法,如果removeEldestEntry方法返回true,且头结点不为空,put方法默认调用后处理方法evict参数就是true,if条件判断3个条件都成立,所以LRUCache 此时会移除head节点。
分类:
Java核心 / 集合
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?