Java使用LinkedHashMap实现LRU缓存

Java使用LinkedHashMap实现LRU缓存


参加拼多多一面的时候手撕了LRU,虽然我知道经常会考LRU,但是自己一直没动手去实现,这里介绍一下LRU以及Java实现

LRU介绍

LRU可以用来当作缓存,每次访问LRU的数据之后,那个数据将变成最新的。往里面添加数据后,若容量超过自己设置的最大容量,将会删除最老的数据。即最早添加的或最长时间未使用的(注意:最早的被访问也会变成最新的)

LRU实现方式

Java实现LRU一般采用链表+HashMap的形式,链表维护顺序,HashMap便于快速查找数据,而不用去遍历链表

  1. LinkedHashMap支持LRU,其本质也是链表和HashMap,可以对其进行改造生成我们所需要的LRU
  2. 自己使用链表和HashMap生成LRU

这里我们首先介绍使用LinkedHashMap实现LRU

LinkedHashMap实现LRU

import java.util.LinkedHashMap;
import java.util.Map;

public class LRU<K, V> {
    /**
     * The head (eldest) of the doubly linked list.
     */
    //transient LinkedHashMap.Entry<K,V> head;
    //LinkedHashMap最前面是最旧的

    //这里设置LinkedHashMap容量,负载因子使用默认的0.75
    private final float loadFactory = 0.75f;
    private LinkedHashMap<K, V> map;

    public LRU(int maxCacheSize) {
        //HashMap达到容量就进行扩容,if ((size >= threshold),因此需要+1
        int capacity = (int)Math.ceil(maxCacheSize / this.loadFactory) + 1;
        //public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder),accessOrder为true表示LRU
        map = new LinkedHashMap<K, V>(capacity, loadFactory, true) {
            //重写removeEldestEntry,当容量超过maxCacheSize会移除first
            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return size() > maxCacheSize;
            }
        };
    }

    public void put(K key, V value) {
        map.put(key, value);
    }

    public V get(K key) {
        return map.get(key);
    }

    public void remove(K key) {
        map.remove(key);
    }

    public boolean contain(K key) {
        return map.containsKey(key);
    }

	//还有一些其他方法可以自己去实现

    public static void main(String[] args) {
        LRU<Integer, Integer> lru = new LRU<Integer, Integer>(2);
        lru.put(1, 1);
        lru.put(2, 2);
        //key = 1会被移除,最旧的
        lru.put(3, 3);
        lru.put(2, 3);
        System.out.println("lru包含key为1的: " + lru.contain(2));
        System.out.println("lru包含key为3的: " + lru.contain(3));
        //key = 3会被移除,因为刚才重置了2的值,2变成最新的了
        lru.put(1, 3);
        System.out.println("lru包含key为3的: " + lru.contain(3));
    }
}

运行结果

lru包含key为1: true
lru包含key为3: true
lru包含key为3: false

Process finished with exit code 0

下一篇我们介绍一下自己使用链表和HashMap实现LRU

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值