时间:2021-03-27来源:www.pcxitongcheng.com作者:电脑系统城
最近在逛博客的时候看到了有关Redis方面的面试题,其中提到了Redis在内存达到最大限制的时候会使用LRU等淘汰机制,然后找了这方面的一些资料与大家分享一下。 LRU总体大概是这样的,最近使用的放在前面,最近没用的放在后面,如果来了一个新的数,此时内存满了,就需要把旧的数淘汰,那为了方便移动数据,肯定就得使用链表类似的数据结构,再加上要判断这条数据是不是最新的或者最旧的那么应该也要使用hashmap等key-value形式的数据结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public class LRUCache { int capacity; Map<Integer,Integer> map; public LRUCache( int capacity){ this .capacity = capacity; map = new LinkedHashMap<>(); } public int get( int key){ //如果没有找到 if (!map.containsKey(key)){ return - 1 ; } //找到了就刷新数据 Integer value = map.remove(key); map.put(key,value); return value; } public void put( int key, int value){ if (map.containsKey(key)){ map.remove(key); map.put(key,value); return ; } map.put(key,value); //超出capacity,删除最久没用的即第一个,或者可以复写removeEldestEntry方法 if (map.size() > capacity){ map.remove(map.entrySet().iterator().next().getKey()); } } public static void main(String[] args) { LRUCache lruCache = new LRUCache( 10 ); for ( int i = 0 ; i < 10 ; i++) { lruCache.map.put(i,i); System.out.println(lruCache.map.size()); } System.out.println(lruCache.map); lruCache.put( 10 , 200 ); System.out.println(lruCache.map); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
public class LRUCache { private int capacity; private Map<Integer,ListNode>map; private ListNode head; private ListNode tail; public LRUCache2( int capacity){ this .capacity = capacity; map = new HashMap<>(); head = new ListNode(- 1 ,- 1 ); tail = new ListNode(- 1 ,- 1 ); head.next = tail; tail.pre = head; } public int get( int key){ if (!map.containsKey(key)){ return - 1 ; } ListNode node = map.get(key); node.pre.next = node.next; node.next.pre = node.pre; return node.val; } public void put( int key, int value){ if (get(key)!=- 1 ){ map.get(key).val = value; return ; } ListNode node = new ListNode(key,value); map.put(key,node); moveToTail(node); if (map.size() > capacity){ map.remove(head.next.key); head.next = head.next.next; head.next.pre = head; } } //把节点移动到尾巴 private void moveToTail(ListNode node) { node.pre = tail.pre; tail.pre = node; node.pre.next = node; node.next = tail; } //定义双向链表节点 private class ListNode{ int key; int val; ListNode pre; ListNode next; //初始化双向链表 public ListNode( int key, int val){ this .key = key; this .val = val; pre = null ; next = null ; } } } |
像第一种方式,如果复写removeEldestEntry会更简单,这里简单的展示一下
1 2 3 4 5 6 7 8 |
public class LRUCache extends LinkedHashMap<Integer,Integer> { private int capacity; @Override protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) { return size() > capacity; } } |
到此这篇关于手动实现Redis的LRU缓存机制的文章就介绍到这了
2023-03-15
Navicat远程连接MongoDB最全实现方法以及报错解决2023-03-15
MongoDB的启动方法详细总结2023-03-11
详解分库分表后非分片键如何查询GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组,下面这篇文章主要给大家介绍了关于高版本Mysql使用group by分组报错的解决方案,文中通过实例代码介绍的非常详细,需要的朋友可以参考下...
2023-03-06