LRUCache的链表+HashMap实现

LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是如果数据最近被访问过,那么将来被访问的几率也更高。

public class LRUCache<K,V> {
	
	static class Node{
		Node pre;
		Node next;
		Object key;
		Object value;
	}

	/**当前缓存对象数量*/
	private int currentCacheSize;
	/**缓存容量*/
	private int cacheCapcity;
	/**缓存 容器*/
	private Map<K, Node> caches;
	/**(实现双链表)链表头*/
	private Node first;
	/**(实现双链表)链表尾*/
	private Node last;

	public LRUCache(int size) {
		this.currentCacheSize = 0;
		this.cacheCapcity = size;
		this.caches = new HashMap<K,Node>(size);
	}
	
	/***
	 * 利用链表和HashMap:
	 * 当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链表头部,
	 * 如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除即可。
	 */
	public void put(K k,V v) {
		Node node = caches.get(k);
		if(null == node) {
			if(caches.size() >= cacheCapcity) {
				caches.remove(last.key);//将最少使用的节点删除
				removeLast();
			}
			currentCacheSize ++;
			node = new Node();
			node.key = k;
		}
		node.value = v;
		moveToFirst(node);//将最新使用的节点放在链表头,表示最新使用的。
		caches.put(k, node);
	}

	/****
	 * 在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部
	 */
	public Object get(K k) {
		Node node = caches.get(k);
		if(null == node) {
			return null;
		}
		moveToFirst(node);
		return node.value;
	}
	
	/***
	 * 移动到链表头,表示这个节点是最新使用过的
	 * @author ZHEN
	 * 2019年5月16日
	 */
	private void moveToFirst(Node node) {
		if(first == node) {
			return;
		}
		if(null != node.next) {
			node.next.pre = node.pre;
		}
		if(null != node.pre) {
			node.pre.next = node.next;
		}
		if(node == last) {
			last = last.pre;
		}
		if(null == first || null == last) {
			first = last = node;
			return;
		}
		node.next = first;
		first.pre = node;
		first = node;
		first.pre = null;
	}

	/**
	 * 删除链表尾部节点  表示 删除最少使用的缓存对象
	 * @author ZHEN
	 * 2019年5月16日
	 */
	private void removeLast() {//链表尾不为空,则将链表尾指向null. 删除链表尾(删除最少使用的缓存对象)  
		if(null != last) {
			last = last.pre;
			if(null == last) {
				first = null;
			}else {
				last.next = null;
			}
		}
	}
	
	public void clear() {
		first = null;
		last = null;
		caches.clear();
	}
	
	public Object remove(K k) {
		Node node = caches.get(k);
		if(null != node) {
			if(null != node.pre) {
				node.pre.next = node.next;
			}
			if(null != node.next) {
				node.next.pre = node.pre;
			}
			if(node == first) {
				first = node.next;
			}
			if(node == last) {
				last = node.pre;
			}
		}
		return caches.remove(k);//HashMap  remove
	}
	
	public static void main(String[] args) {
		
		LRUCache<Object, Object> lruCache = new LRUCache<>(3);
		
		Object remove = lruCache.remove("k1");
		
		System.out.println(remove);
		
		lruCache.put("k1", "v1");
		lruCache.put("k2", "v2");
		lruCache.put("k3", "v3");
		lruCache.put("k4", "v4");
		
		System.out.println(lruCache.caches);
		System.out.println(lruCache.first);
		lruCache.get("k2");
		
		System.out.println(lruCache.first);
	}
}
原创文章 6 获赞 6 访问量 250

猜你喜欢

转载自blog.csdn.net/Aoico/article/details/105813910