LinkedHashMap Q&A

LinkedHashMap 在初始化的时候,有两种使用模式

  • 插入顺序 ,遍历时,按照put顺序输出
  • 访问顺序,这种情况下是否会扩容 ????
  • 当处于访问顺序模式的时候,什么情况下会删除eldest 元素。

HashMap 是无序的 。那么LinkedHashMap 是如何保持有序的

  • HashMap 以拉链法处理冲突, 数组下标对应的是 元素的hash 值 对数组长度的求余。
  • LinkedHashMap 使用双向链表来,保持顺序和方便操作

LinkedHashMap 是HashMap 的子类 ,它是如何在不侵入 HashMap的 前提下 实现双向链表的功能

  • put 一个新的元素的 时候,会触发 Node 的创建, LinkedHashMap 重写了创建的过程,在Node创建的时候建立和维护双向链表

双向链表的维护操作 : put(Key不存在) ,put (Key存在),删除

  • 最简单的删除操作, HashMap 在删除一个 Node 也就是 Entry 后会调用 afterNodeRemoval 方法 。LinkedHashMap 覆写了这个方法,由于是双向链表,所以删除操作很快。
  • put(Key不存在) 会 调用 afterNodeInsertion(boolean evict) 。这个方法是干嘛的呢? 当evict 为True 的时候,且 处于LRU 模式,会触发维护访问次序的方法。
    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);
        }
    }

上面的 移除逻辑需要满足 removeEldestEntry(first) 为 true 。
默认情况下 ,是不会移除EldestEntry 。
如要要实现LRU ,需要 手动移除,或者 继承 LinkedHashMap 并且 重写这个方法。

    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return false;
    }

访问顺序的维护

先明确一点,在访问模式下:

  • 最近访问的元素,是放在链表的尾部。
  • 很久不使用的元素,放在链表的头部。

当我们调用get/getOrDefault/replace等方法时 会触发 afterNodeAccess 方法,把对应的Node 移动到双向链表的尾部

实现一个最简单的 LRUCache

leetcode 146题

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
public class LRUCache extends LinkedHashMap<Integer, Integer>  {

    int maxCapacity;
    public LRUCache(int capacity) {

        super(16,0.75f,true);
        maxCapacity = capacity;
    }

    public int get(int key) {
        return  super.getOrDefault(key,-1);
    }

    public void put(int key, int value) {
        super.put(key,value);
    }

    @Override
    protected boolean removeEldestEntry(Entry eldest) {
        return size()>maxCapacity;
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值