一、LRU算法
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
也就是说当我压入一个新元素A到数据结构中,会存在三种情况:
1.数据结构中存在A,先移除A,再压入A(更新时间)
2.数据结构不存在A,但是数据结构容量还够,直接压入
3.数据结构中不存在A,但是数据结构容量不够,把最久没有使用的去掉,再把A压入
选取数据结构:
因为其中要记录压入元素的时间,那么我们自然想到越早压入就应该越在前面,因此就会想到跟压入顺序有关,那么LinkedHashMap就可以保存压入顺序。因为里面还要比较是否有相同的没,要把相同的移除。用HashMap这种结构就很方便,因为是hash查询O(1)复杂度。
但是存在一个问题,就把LinkedHashMap第一个元素去除,那么我们就要用到Iterable 去实现迭代器。用next去取第一个元素,就可以知道最久没有使用了。
二、代码
public class LRUCache<K, V> implements Iterable<K> {
int MAX = 3;
//实现LRU
LinkedHashMap<K, V> cache = new LinkedHashMap<>();
@Override
public Iterator<K> iterator() {
//每次调用遍历器都是将最新的数据更新到这里
Iterator<Map.Entry<K, V>> it = cache.entrySet().iterator();
return new Iterator<K>() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public K next() {
return it.next().getKey();
}
};
}
public void cache(K key , V value){
if(cache.containsKey(key)){
cache.remove(key);
}else if(cache.size() >= MAX){
Iterator<K> it = cache.keySet().iterator();
K next = it.next();
cache.remove(next);
}
cache.put(key, value);
}
public static void main(String[] args) {
LRUCache<String, Integer> lru = new LRUCache<>();
lru.cache("A", 1);
lru.cache("B", 2);
lru.cache("C", 3);
lru.cache("D", 4);
lru.cache("C", 10);
System.out.println(
"leave <-" + StreamSupport.stream(lru.spliterator(), false)
.map(x -> x.toString())
.collect(Collectors.joining("<-")));
}
}