用java实现LRU

1.用双向链表+HashMap

/**
1.新建一个LRUCache类,里面维护一个HashMap,保存数据
2.维护一个链表,当数据每一次命中就将数据放到链表的head,当有新数据添加时也放到head。这样链表的尾部就是最近最久未使用的,
每次容量不足时就可以删除tail,显然这是一个双向链表结构,因此我们定义一个LRUNode结构
*/
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class First {
    class Node {
        int key;
        int value;
        Node pre;
        Node next;
        public Node(int key,int value){
            this.key = key;
            this.value = value;
        }
    }
    int capacity;
    HashMap<Integer,Node> map = new HashMap<Integer,Node>();
    Node head = null;
    Node end = null;
    
    public First(int capacity) {
        this.capacity = capacity;
    }

    public int get(int key) {
        if(map.containsKey(key)){
            Node n = map.get(key);
            remove(n);
            setHead(n);
            return n.value;
        }
        return -1;
    }
    public void remove(Node n){
        if(n.pre!=null){
            n.pre.next = n.next;
            
        }else{
            head = n.next;
        }
        if(n.next!=null){
            n.next.pre = n.pre;
            
        }else{
            end = n.pre;
        }
    }
    public void setHead(Node n){
        n.next = head;
        n.pre = null;
        if(head!=null){
            head.pre = n;
        }
        head = n;
        if(end == null) end = head;
    }
     public void put(int key,int value){
         if(map.containsKey(key)){
             Node old = map.get(key);
             old.value = value;
             remove(old);
             setHead(old);
         }else {
        	 Node created = new Node(key,value);
        	 if(map.size()>=capacity) {
        		 map.remove(end.key);
        		 remove(end);
        		 setHead(created);
        	 }else {
        		 setHead(created);
        	 }
        	 map.put(key, created);
         }
     }
}

2.用LinkedHashMap

package cn.LRU;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
 LinkedHashMap 除了值是有序的之外,还可以自动删除最前面保存的值。
LinkedHashMap 中有一个 removeEldestEntry 方法,如果这个方法返回 true,Map 
中最前面添加的内容将被删除,它是在添加属性的 put 或 putAll 方法被调用后自动调用的。
这个功能主要是用在缓存中,用来限定缓存的最大数量,以防止缓存无限制地增长。
 */
public class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V>{

	private final int maxCapacity;
	private static final float DEFAULT_LOAD_FACTOR = 0.75f;
	private final Lock lock = new ReentrantLock();
	public LRULinkedHashMap(int maxCapacity) {
		super(maxCapacity,DEFAULT_LOAD_FACTOR,true);
		this.maxCapacity = maxCapacity;
	}
    
	public boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
		return size()> maxCapacity;
	}
	public boolean containsKey(Object key) {
		try {
			lock.lock();
			return super.containsKey(key);	
		}finally {
			lock.unlock();
		}
		
	}
	
	public boolean containskey(Object key) {
		try {
			lock.lock();
			return super.containsKey(key);
		}finally {
			lock.unlock();
		}
	}
	@Override 
    public V get(Object key) {  
        try {  
            lock.lock();  
            return super.get(key);  
        } finally {  
            lock.unlock();  
        }  
    }  

    @Override 
    public V put(K key, V value) {  
        try {  
            lock.lock();  
            return super.put(key, value);  
        } finally {  
            lock.unlock();  
        }  
    }  

    public int size() {  
        try {  
            lock.lock();  
            return super.size();  
        } finally {  
            lock.unlock();  
        }  
    }  

    public void clear() {  
        try {  
            lock.lock();  
            super.clear();  
        } finally {  
            lock.unlock();  
        }  
    }  

    public Collection<Map.Entry<K, V>> getAll() {  
        try {  
            lock.lock();  
            return new ArrayList<Map.Entry<K, V>>(super.entrySet());  
        } finally {  
            lock.unlock();  
        }  
    }  

}

### 回答1: 使用 Java 实现 LRU 算法的基本步骤是:1. 定义一个双向链表;2. 重写put()和get()方法;3. 在put()方法中,如果元素已存在,移动到链表头部;4. 在get()方法中,如果元素存在,移动到链表头部;5. 如果缓存已满,移除链表尾部的元素。 ### 回答2: 使用Java实现lru算法可以通过使用LinkedHashMap来实现。 LinkedHashMap是HashMap的子类,它通过维护一个双向链表来记录插入顺序。我们可以利用LinkedHashMap的特性来实现lru算法。 具体实现步骤如下: 1. 创建一个继承自LinkedHashMap的子类LRUMap,指定其泛型为<K, V>。 2. 重写LRUMap的构造方法,传入一个capacity参数来指定LRUMap的容量,并调用父类LinkedHashMap的构造方法来初始化LRUMap。 3. 在重写的构造方法中,使用super(capacity, 0.75f, true)来调用父类构造方法,并将最后一个参数设置为true,表示开启访问顺序模式。 4. 重写LRUMap的removeEldestEntry方法,当LRUMap的大小超过指定容量时,移除最老的键值对。 5. 至此,我们已经完成了LRUMap的实现。 下面是一个使用LRUMap的示例: ```java import java.util.LinkedHashMap; public class LRUMap<K, V> extends LinkedHashMap<K, V> { private final int capacity; public LRUMap(int capacity) { super(capacity, 0.75f, true); this.capacity = capacity; } @Override protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return size() > capacity; } public static void main(String[] args) { LRUMap<String, Integer> lruMap = new LRUMap<>(3); lruMap.put("a", 1); lruMap.put("b", 2); lruMap.put("c", 3); lruMap.put("d", 4); System.out.println(lruMap); // 输出: {b=2, c=3, d=4} } } ``` 以上示例中,我们创建了一个容量为3的LRUMap,并进行了插入操作。当容量超过3时,最老的键值对"a"会被移除,而最新的键值对"d"则会按照访问顺序保存在LRUMap中。最后,我们打印出LRUMap的内容,验证了LRU算法的实现。 ### 回答3: LRU(Least Recently Used,最近最少使用)是一种常见的缓存淘汰算法,其中使用Java实现LRU算法的原理是根据数据的使用情况对缓存中的数据进行淘汰,将最近最少使用的数据移除,以腾出空间存储新的数据。 在Java中,我们可以使用LinkedHashMap来实现LRU算法。LinkedHashMap是HashMap的子类,它可以保持插入顺序或访问顺序。 下面是一个简单的使用Java实现LRU算法的示例代码: ```java import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends LinkedHashMap<K, V> { private int capacity; // 缓存容量 public LRUCache(int capacity) { super(capacity, 0.75f, true); // 设置访问顺序为true,保持LRU特性 this.capacity = capacity; } @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; // 当缓存大小超过容量时,移除最久未使用的数据 } public static void main(String[] args) { LRUCache<Integer, String> cache = new LRUCache<>(3); cache.put(1, "A"); cache.put(2, "B"); cache.put(3, "C"); System.out.println(cache); // 输出:{1=A, 2=B, 3=C} cache.put(4, "D"); System.out.println(cache); // 输出:{2=B, 3=C, 4=D} cache.get(2); System.out.println(cache); // 输出:{3=C, 4=D, 2=B} } } ``` 在以上示例代码中,我们继承了LinkedHashMap,并重写了`removeEldestEntry`方法,当缓存大小超过容量时,会自动移除最久未使用的数据。 通过以上代码,我们可以使用Java实现LRU算法,并对缓存中的数据进行淘汰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值