LRU算法源码实现

算法介绍:
最近最久未使用(Least Recently Used    LRU)算法是⼀种缓存淘汰策略。该算法的思路是,将最近一段时间内最久未使用的页面置换出去。 升级版LRUK算法见

基于LRU-K算法设计本地缓存实现流量削峰https://blog.csdn.net/love254443233/article/details/82598381?spm=1001.2014.3001.5502


import java.util.HashMap;
import java.util.Map;

/**
 * Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
 * 

* Implement the LRUCache class: *

* LRUCache(int capacity) Initialize the LRU cache with positive size capacity. * int get(int key) Return the value of the key if the key exists, otherwise return -1. * void put(int key, int value) Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key. * The functions get and put must each run in O(1) average time complexity. */ public class LRUCache { static class Node { Node prev; Node next; int key; int value; public Node() { } public Node(int key, int value) { this.key = key; this.value = value; } } Map cachMap = new HashMap<>(16); Node head; Node end; int size; int capacity; public LRUCache(int capacity) { this.size = 0; this.capacity = capacity; head = new Node(); end = new Node(); head.next = end; end.prev = head; } public int get(int key) { Node node = cachMap.get(key); if (node == null) { return -1; } // 移动到链表头 moveToHead(node, head); return node.value; } public void put(int key, int value) { Node node = cachMap.get(key); if (node == null) { Node data = new Node(key, value); cachMap.put(key, data); addToHead(data, head); ++size; if (size > capacity) { cachMap.remove(end.prev.key); delete(end.prev); --size; } return; } node.value = value; moveToHead(node, head); } /** * 添加到链表头 * * @param node 数据节点 * @param head 头节点 */ private static void addToHead(Node node, Node head) { node.next = head.next; node.prev = head; head.next = node; node.next.prev = node; } /** * 移除当前节点 * * @param data 数据节点 */ private static void delete(Node data) { if (data.prev != null) { Node prev = data.prev; prev.next = data.next; data.next.prev = prev; } } /** * 把节点移动到链表头 * * @param node 节点 * @param head 头节点 */ private static void moveToHead(Node node, Node head) { // 移除node delete(node); // 把node添加到链表头 addToHead(node, head); } }

单元测试

import junit.framework.TestCase;
import org.junit.Assert;

public class LRUCacheTest extends TestCase {

    public void testGet() {
        LRUCache lruCache = new LRUCache(2);
        // node 为空,结果为-1
        Assert.assertEquals(-1, lruCache.get(1));

        // node存在
        lruCache.put(1, 2);
        Assert.assertEquals(2, lruCache.get(1));

        // node存在,重复put
        lruCache.put(1, 3);
        Assert.assertEquals(3, lruCache.get(1));

        // cache数量超过容器数量,会移除链表尾节点
        lruCache.put(2, 3);
        lruCache.put(3, 4);
        Assert.assertEquals(-1, lruCache.get(1));
    }
}

你可能感兴趣的:(算法,算法,java,开发语言)