前言:之前有写过一篇关于LRU的文章链接

 解释:上面这个图就是一个LRU的简单实现思路,在链表的开始插入元素,然后每插入一次计数一次,接着按照次数重新排序链表,如果次数相同的话,按照插入时间排序,然后从链表尾部选择淘汰的数据~

二:LRU实现

2.1 定义Node节点

Node主要包含了key和value,因为LFU的主要实现思想是比较访问的次数,如果在次数相同的情况下需要比较节点的时间,越早放入的越快      被淘汰,因此我们需要在Node节点上加入time和count的属性,分别用来记录节点的访问的时间和访问次数。其他的版本实现方式里有新加个内部类来记录 key的count和time,但是我觉得不够方便,还得单独维护一个map,成本有点大。还有一点注意的是这里实现了comparable接口,覆写了compare方法,这里 的主要作用就是在排序的时候需要用到,在compare方法里面我们首先比较节点的访问次数,在访问次数相同的情况下比较节点的访问时间,这里是为了 在排序方法里面通过比较key来选择淘汰的key

复制代码
 /**      * 节点      */    public static class Node implements Comparable<Node>{             //            Object key;             //            Object value;             /**              * 访问时间              */            long time;              /**              * 访问次数              */            int count;              public Node(Object key, Object value, long time, int count) {                 this.key = key;                 this.value = value;                 this.time = time;                 this.count = count;             }              public Object getKey() {                 return key;             }              public void setKey(Object key) {                 this.key = key;             }              public Object getValue() {                 return value;             }              public void setValue(Object value) {                 this.value = value;             }              public long getTime() {                 return time;             }              public void setTime(long time) {                 this.time = time;             }              public int getCount() {                 return count;             }              public void setCount(int count) {                 this.count = count;             }              @Override             public int compareTo(Node o) {                 int compare = Integer.compare(this.count, o.count);                 //在数目相同的情况下 比较时间                if (compare==0){                     return Long.compare(this.time,o.time);                 }                 return compare;             }         }
复制代码

 2.2:定义LFU类

 定义LFU类,这里采用了泛型,声明了K和V,还有总容量和一个Map(caches)用来维护所有的节点。在构造方法里将size传递进去,并且创建了一个LinkedHashMap,采用linkedHashMap的主要原因是维护key的顺序