LRU算法的实现
Posted jarjune
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LRU算法的实现相关的知识,希望对你有一定的参考价值。
缘由:看到redis的缓存淘汰机制,便自己实现了一下
代码实现(双向链表+HashMap)
package com.jarjune.jdalao.framework.algorithm;
import java.util.*;
/**
* LRU
* @author jarjune
* @version 1.0.1
* @date 2020/11/19
*/
public class LRUCache<K, V> {
// 缓存Node
private Map<K, Node<K, V>> cache;
// 双向链表首结点
private Node<K, V> first;
// 双向链表尾结点
private Node<K, V> last;
// 最大缓存容量
private int capacity;
public LRUCache(int capacity) throws Exception {
if(capacity < 2) {
throw new Exception("capacity小于2就没啥意义了...");
}
this.cache = new HashMap<>((int) (capacity / 0.75f + 1));
this.capacity = capacity;
}
private class Node<K, V> {
K k;
V v;
Node<K, V> prev;
Node<K, V> next;
Node(K k, V v) {
this.k = k;
this.v = v;
}
@Override
public String toString() {
return "Node{" +
"k=" + k +
", v=" + v +
‘}‘;
}
}
public int size() {
return cache.size();
}
public void put(K k, V v) {
Node<K, V> node = cache.get(k);
if(null == node) {
node = new Node<>(k, v);
// 大于等于capacity容量最大值时
if(cache.size() >= capacity) {
if(null != last) {
// 移除最后一个元素的缓存
cache.remove(last.k);
last = last.prev;
if(null == last) {
first = null;
} else {
last.next = null;
}
}
}
cache.put(k, node);
} else {
node.v = v;
}
moveToFirst(node);
}
/**
* 1(first)
* ↑ ↓
* 2(node)
* ↑ ↓
* 3
* ↑ ↓
* 4(last)
*/
private void moveToFirst(Node<K, V> node) {
if(first == null || last == null) {
first = last = node;
return;
}
// 如果是头结点就结束
if(node == first) {
return;
}
// 如果是尾结点,尾结点就等于当前结点的上一个结点
if(node == last) {
last = node.prev;
}
if(null != node.next) {
node.next.prev = node.prev;
}
if(null != node.prev) {
node.prev.next = node.next;
}
node.next = first;
first.prev = node;
node.prev = null;
first = node;
}
class LRUIterable implements Iterable<Node<K, V>> {
@Override
public Iterator<Node<K, V>> iterator() {
return new Iterator<Node<K, V>>() {
private Node<K, V> node = first;
@Override
public boolean hasNext() {
return node != null;
}
@Override
public Node<K, V> next() {
Node<K, V> tmp = node;
node = node.next;
return tmp;
}
};
}
}
public Iterator<Node<K, V>> iterator() {
return new LRUIterable().iterator();
}
public Set<K> keySet() {
Iterator<Node<K, V>> iterator = iterator();
Set<K> keys = new LinkedHashSet<>();
while(iterator.hasNext()) {
keys.add(iterator.next().k);
}
return keys;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Node<K, V> node: new LRUIterable()) {
sb.append(node);
}
return sb.toString();
}
}
搞定
以上是关于LRU算法的实现的主要内容,如果未能解决你的问题,请参考以下文章