实现LRU Cache(java版)

2 篇文章 0 订阅

LRU算法,也叫最近最少使用算法,我们可以使用该算法来实现cache机制,简单地说就是缓存一定量的数据,当超过设定阀值的时候就把一些过期的数据删除掉,本篇文章我们来看看如何实现LRU Cache,下面我们使用两种方式来实现。

基于LinkedHashMap

在java的集合类中有LinkedHashMap类,当参数accessOrder为true的时候,就会按照访问顺序排序,最后访问的放在最前面,最早访问的放在后面,这样我们就可以实现LRU算法了。这种方式比较简单,代码如下:

public class LRU {
	private final int CAPACITY=0;
	private LinkedHashMap<Integer,Integer> cache;
	
	public LRU(int capacity){
		cache=new LinkedHashMap<Integer,Integer>(capacity,0.75f,true){
			@Override
			protected boolean removeEldestEntry(java.util.Map.Entry<Integer, Integer> eldest) {
				return size()>CAPACITY;
			}
		};
	}
	
	public int get(int key) {
        return cache.getOrDefault(key, -1);
    }
    
    public void put(int key, int value) {
        cache.put(key, value);
    }
	
}
链表+HashMap

第二种方式是使用链表+HashMap的方式来实现,需要我们自己实现一系列方法,代码如下:

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
/**
 * LRUCache链表+hashmap的实现方式
 * @author shinelon
 *
 */
public class LRUCache2<K,V>{
	
	public final int CACHE_SIZE;
	public Entry frist;
	public Entry last;
	public HashMap<K,Entry<K,V>> hashMap;
	
	public LRUCache2(int cacheSize){
		this.CACHE_SIZE=cacheSize;
		hashMap=new HashMap<K,Entry<K,V>>();
	}
	
	public void put(K key,V value){
		Entry entry=getEntry(key);
		if(entry==null){
			if(hashMap.size()>=CACHE_SIZE){
				hashMap.remove(last.key);
				removeLast();
			}
			entry=new Entry();
			entry.key=key;
		}
		entry.value=value;
		moveToFrist(entry);
		hashMap.put(key, entry);
	}
	
	public V get(K key){
		Entry<K,V> entry=getEntry(key);
		if(entry==null)
			return null;
		moveToFrist(entry);
		return entry.value;
	}
	

	private void moveToFrist(Entry entry) {
		if(entry==frist)
			return;
		if(entry.pre!=null)
			entry.pre.next=entry.next;
		if(entry.next!=null)
			entry.next.pre=entry.pre;
		if(last==entry)
			last=last.pre;
		
		if(frist==null||last==null){
			frist=last=entry;
			return;
		}
		
		entry.next=frist;
		frist.pre=entry;
		frist=entry;
		frist.pre=null;
	}

	private void removeLast() {
		if(last!=null){
			last=last.pre;
			if(last==null)
				frist=null;
			else
				last.next=null;
		}
	}
	

	public Entry getEntry(K key){
		return hashMap.get(key);
	}
	
	public void print(HashMap<K,Entry<K,V>> map){
		Collection<Entry<K,V>> entry=map.values();
		Iterator it=entry.iterator();
		while(it.hasNext()){
			Entry<K,V> e=(LRUCache2<K, V>.Entry<K, V>) it.next();
			System.out.println(e.key+"  :  "+e.value);
		}
	}

	class Entry<K,V>{
		Entry pre;
		Entry next;
		K key;
		V value;
	}
	
	
	public static void main(String[] args) {
		LRUCache2<String, String> cache=new LRUCache2<>(3);
		cache.put("one", "1");
		cache.put("tow", "2");
		cache.put("three", "3");
		System.out.println("first entry: "+cache.frist.key);
		cache.print(cache.hashMap);
		cache.put("four", "4");
		System.out.println("============================");
		System.out.println("first entry: "+cache.frist.key);
		cache.print(cache.hashMap);
		cache.put("five", "5");
		System.out.println("============================");
		System.out.println("first entry: "+cache.frist.key);
		cache.print(cache.hashMap);
	}
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值