【经典LRU算法java版本】

左神yyds系列

package Code01;

import java.util.HashMap;

/*
 * LRU算法:使用哈希表和双向链表
 * 算法思路:存储最近使用的数据,可以自行设置存储个数,最近新增与修改的数据会自动放在末尾
 * */

public class Demo04 {
	
	public static void main(String[] args) {
		LRU<String, String> lru = new LRU(3);
		lru.set("A", "one");
		lru.set("B", "two");
		lru.set("C", "three");
		lru.set("D", "four");
		lru.get("B");
		lru.set("D", "five");
		while(lru.doubleLinkedList.head != lru.doubleLinkedList.tail.next) {
			System.out.println(lru.doubleLinkedList.head.value);
			lru.doubleLinkedList.head = lru.doubleLinkedList.head.next;
		}
	}
}
class LRU<k, v> {
	public HashMap<k, Node<k, v>> keyHashMap;
	public int capacity;
	public DoubleLinkedList<k, v> doubleLinkedList;
	
	public LRU(int capacity) {
		this.keyHashMap = new HashMap<>();
		this.doubleLinkedList = new DoubleLinkedList<>();
		this.capacity = capacity;
	}
	
	public v get(k key) {
		if(keyHashMap.containsKey(key)) {
			Node node = keyHashMap.get(key);
			this.doubleLinkedList.change(node);
			return (v) node.value;
		}
		return null;
	}
	
	public void set(k key, v value) {
		if(keyHashMap.containsKey(key)) {
			Node<k, v> node = keyHashMap.get(key);
			node.value = value;
			this.doubleLinkedList.change(node);
		}else {
			Node<k, v> node = new Node<>(key, value);
			keyHashMap.put(key, node);
			if(this.capacity+1 == keyHashMap.size()) {
				this.doubleLinkedList.removeHead();
				this.keyHashMap.remove(key);
			}
			this.doubleLinkedList.addNode(node);
		}
	}
}
class Node<k, v> {
	public k key;
	public v value;
	public Node<k, v> next;
	public Node<k, v> last;
	
	public Node(k key, v value) {
		this.key = key;
		this.value = value;
	}
}
class DoubleLinkedList<k, v> {
	public Node<k, v> head;
	public Node<k, v> tail;
	
	public DoubleLinkedList() {
		this.head = null;
		this.tail = null;
	}
	
	// 增加节点
	public void addNode(Node<k, v> node) {
		if(node == null) {
			return;
		}
		if(head == null) {
			head = node;
			tail = node;
		}else {
			tail.next = node;
			node.last = tail;
			tail = node;
		}
	}
	
	// 将节点移至结尾的位置
	public void change(Node<k, v> node) {
		if(node == null || node == tail) {
			return;
		}
		if(node == head) {
			head = node.next;
			node.next.last = null;
		}else {
			node.last.next = node.next;
			node.next.last = node.last;
		}
		tail.next = node;
		node.last = tail;
		tail = node;
		node.next = null;
	}
	
	// 移除头节点
	public Node<k, v> removeHead() {
		if(head == null) {
			return null;
		}
		Node<k, v> temp = null;
		if(head == tail) {
			head = null;
			tail = null;
		}else {
			temp = head;
			head = temp.next;
			temp.next.last = head;
		}
		return temp;
	}	
}

你可能感兴趣的:(左神yyds系列,java,算法,数据结构)