//添加的数据类型
package com.lin; import java.util.Objects; public class LRUData <T> { T val; LRUData next; public LRUData(T t){ this.val =t; } @Override public boolean equals(Object o) { if(o instanceof LRUData){ return this.val.equals(((LRUData) o).val); } return false; } @Override public int hashCode() { return Objects.hash(val); } }
//缓存区 用一个简易的链表来维持,并提供一些基本的操作
package com.lin; /** * 维持一个链表 */ public class LRUList<T> { public static int DEFAULT_SIZE = 10; //该链表容量大小 默认为10 int num;//表示链表中有多少个 int capacity;//表示链表的容量 (即缓存区间) LRUData<T> head; public LRUList(int capacity) { this.capacity = capacity; } public LRUList() { this.capacity = DEFAULT_SIZE; this.num = 0; head=null; } //获取数据 没有返回空 有则将数据置于链表首端 public T get(T data){ LRUData<T> lruData = new LRUData<T>(data); LRUData<T> tmp = head; LRUData<T> previous = head; while (tmp!=null){ //移到最前面 if(lruData == tmp){ previous.next=tmp.next; tmp.next=head; head=tmp; return tmp.val; } previous =tmp; //指向前一个节点 tmp=tmp.next; } return null; }
//添加数据 public void addFirst(T data) { LRUData<T> lruData = new LRUData<>(data); if (num <= capacity) { if (head == null) { head = lruData; num++; }else{ lruData.next =head; head=lruData; num++; } }else{ LRUData tmp = head; LRUData pervious = head; while (tmp.next!=null){ pervious=tmp; tmp=tmp.next; } pervious.next=null; //倒数第二个的next置为空; tmp=null ;//释放对象 } }}
这个算法的核心就是两个方法一个get和一个addFirst, 当我们get数据时若有会将该数据置于头部,若没有则使用addFirst加入,由于限制的缓存区大小,在加入时,会判断如果没满直接头部加入,满了的话还需要移除末尾,为了效率(当然为了效率起见你可以修改我的list结构 维持一个倒数第二个元素指针 不过需要注意一下链表个数小于而的情况,这个就留个读者自行完成吧)