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();
}
}
}