先一篇泛型总结得很好的博客:https://segmentfault.com/a/1190000014120746
用双向链表实现LRU,要求可以指定缓存大小,并且可以存储任意类型的数据。
(要求用泛型,只需要实现添加方法即可)。
分析:
1.LRU实现
操作:
添加:是否存在?存在-删除-添加到表头; 不存在-看表长?删除末尾添加到表头 or 直接添加到表头
删除:查找,存在-删除
数据结构:带表头双链表
2.任意类型数据-泛型实现
1 package day3practice; 2 3 4 public class GenericParadigm { 5 public static void main(String args[]){ 6 ListLRUGenne<Integer> lru = new ListLRUGenne<>(6,new NodeGenne()); 7 lru.addNodeLRU(5); 8 lru.addNodeLRU(4); 9 lru.addNodeLRU(3); 10 lru.addNodeLRU(2); 11 lru.addNodeLRU(1); 12 lru.printLRU(); 13 lru.addNodeLRU(6); 14 lru.printLRU(); 15 lru.addNodeLRU(3); 16 lru.printLRU(); 17 lru.addNodeLRU(7); 18 lru.printLRU(); 19 // 20 ListLRUGenne<String> lru2 = new ListLRUGenne<>(6,new NodeGenne()); 21 lru2.addNodeLRU("一护"); 22 lru2.addNodeLRU("鸣人"); 23 lru2.addNodeLRU("路飞"); 24 lru2.addNodeLRU("奇伢"); 25 lru2.addNodeLRU("爱德华"); 26 lru2.printLRU(); 27 lru2.addNodeLRU("兵长"); 28 lru2.printLRU(); 29 lru2.addNodeLRU("奇伢"); 30 lru2.printLRU(); 31 lru2.addNodeLRU("柯南"); 32 lru2.printLRU(); 33 34 35 } 36 }
1 package day3practice; 2 3 4 public class ListLRUGenne<T> { //带头结点的单链表,根据题意,所有结点值不同 5 static int lenLimit; 6 static NodeGenne headNode = new NodeGenne(); 7 public ListLRUGenne(int lenLimit,NodeGenne headNode){ 8 this.lenLimit = lenLimit; 9 this.headNode = headNode; 10 } 11 12 static public int length(){ 13 int length = 0; 14 NodeGenne scan = headNode; 15 while(scan.next!=null){ 16 scan=scan.next; 17 length++; 18 19 } 20 return length; 21 } 22 23 //LRU算法的添加的逻辑: 24 public void addNodeLRU(T value){ 25 NodeGenne newone = new NodeGenne(value);//先创建一个待加入的新结点 26 NodeGenne p = headNode;//p是扫描指针 27 28 while(p.value != newone.value&&p.next!=null){ 29 p=p.next; 30 } 31 //出循环两种可能,遍历结束没有找到,或者是找到了 32 if(p.next == null){//遍历完了没有找到 33 int len= ListLRUGenne.length(); 34 if(len<lenLimit){ //不需要删除操作,直接在头部添加 35 addNode(headNode,newone); 36 37 }else{ 38 //先删除最后一个结点 39 deleteNode(p); 40 //再在列表头部添加 41 addNode(headNode,newone); 42 43 } 44 }else{ //找到了这个结点,删除,在头部添加 45 deleteNode(p); 46 addNode(headNode,newone); 47 } 48 } 49 50 public void deleteNode(NodeGenne p){ 51 if(p.next == null){ 52 p.pre.next = null; //删除的是尾结点 53 } 54 else{//删除的是中间结点 55 p.pre.next = p.next; 56 p.next.pre = p.pre; 57 } 58 } 59 60 //双链表添加结点 61 public void addNode(NodeGenne p,NodeGenne newone){ 62 if(p.next == null){ //末尾添加 63 p.next = newone; 64 newone.pre = p; 65 }else{ // 中间添加 66 newone.next = p.next; 67 newone.pre = p; 68 p.next.pre = newone; 69 p.next = newone; 70 } 71 72 } 73 74 public void printLRU(){ 75 NodeGenne p = headNode; 76 if(p.next == null) System.out.println("LRU链表当前无结点"); 77 while(p.next!= null){ 78 p = p.next; 79 System.out.print(p.value+" "); 80 } 81 System.out.println(); 82 } 83 }
1 package day3practice; 2 3 public class NodeGenne <T>{ 4 T value; 5 NodeGenne next=null; 6 NodeGenne pre = null; 7 8 public NodeGenne(T value, NodeGenne next,NodeGenne pre){ 9 this.value = value; 10 this.next = next; 11 this.pre = pre; 12 } 13 public NodeGenne(T value){ 14 this.value = value; 15 } 16 public NodeGenne(){ 17 } 18 19 }
//用双向链表实现LRU,要求可以指定缓存大小,并且可以存储任意类型的数据。
// (要求用泛型,只需要实现添加方法即可)。
//分析:
/*1.LRU实现
操作:
添加:是否存在?存在-删除-添加到表头; 不存在-看表长?删除末尾添加到表头 or 直接添加到表头
删除:查找,存在-删除
数据结构:带表头双链表
2.任意类型数据-泛型实现
*/