简单LRU缓存实现

链表保存键值,由于没有权值策略,简单的将当前访问过的节点放到链表头部,则存在如下问题:

在周期性访问中,某个周期中存在一部分数据仅仅只访问了一次,则最终导致缓存中的数据都是无效的数据,而将频繁访问的数据排除了。在实际应用中,这种简单策略不适用。

TestCode


public class LRUCacheTest {

/**
* @param args
*/
public static void main(String[] args) {
LRUCache cache = new LRUCache(10);

for(int i=0;i<100;i++)
{
cache.put(i+"", "hello_"+i);
// System.out.println(cache.size());
}
cache.printFrontTrace();
System.out.println();
cache.printBackwardTrace();
System.out.println("\n-------------");
cache.remove("90");
cache.printFrontTrace();
System.out.println();
cache.printBackwardTrace();


System.out.println("\n"+cache.get("92"));
System.out.println("\n-------------");

cache.printFrontTrace();

System.out.println("\n"+cache.get("91"));//get tail
System.out.println("\n-------------");
cache.printFrontTrace();

System.out.println("\n"+cache.get("91"));//get head
System.out.println("\n-------------");
cache.printFrontTrace();

cache.remove("91");//remove head
System.out.println("\n-------------");
cache.printFrontTrace();
//
cache.remove("93");//remove tail
System.out.println("\n-------------");
cache.printFrontTrace();


for(int i=0;i<100;i++)//remove all
{
cache.remove(i+"");
// System.out.println(cache.size());
}
System.out.println("\n-------------now size = "+cache.size());
cache.printFrontTrace();
}

}



LRU缓存类,采用双向链表保存键,Hash保存值

package org.jf.alg.lru;

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

/**
*
* LRU 简单实现
* 双向链表+HashMap
* @author chenjf
*
*/
public class LRUCache
{

private KeyNode head;//key值的链表头 (包含数据)
private KeyNode tail;//key值的链表尾 (包含数据)
private int capacity;
private int size;


private Map<Object,CacheObject> map = new HashMap<Object,CacheObject>();



public LRUCache(int capacity)
{
this.capacity=capacity;
}



public void put(Object key,Object value)
{
if(value==null)
return;
Object obj = this.get(key);
if(obj!=null)
return;


KeyNode node = new KeyNode(key);
CacheObject cache_obj = new CacheObject(node,value);
map.put(key, cache_obj);
if(head==null)
{
head = node;
tail = node;
size++;
}else
{
head.previous = node;
node.next = head;
head = node;
size++;
if(size>capacity)
{
remove(tail.key);
}

}


}

public Object remove(Object key)
{
Object data = null;
Object obj = map.remove(key);
if(obj!=null)
{
CacheObject cache_obj = (CacheObject)obj;
KeyNode node = cache_obj.keyNode;
if(size==1)
{
head = null;
tail = null;
}else
{
if(node.equals(head))
{
if(head.next!=null)//not tail
head.next.previous = null;
head = head.next;
node.next = null;

}else if(node.equals(tail))
{
tail = node.previous;
if(tail!=null)
{
tail.next = null;
}
node.previous = null;
}else// not head and tail
{
node.previous.next=node.next;
node.next.previous=node.previous;
node.previous=null;
node.next=null;
}

}
data = cache_obj.data;
size--;
}

return data;
}

public Object get(Object key)
{

Object data = null;
Object obj = map.get(key);
if(obj!=null)
{
CacheObject cache_obj = (CacheObject)obj;

KeyNode node = cache_obj.keyNode;
if(!node.equals(head))//if node is head, nothing to do
{

node.previous.next = node.next;
if(node.next!=null)
node.next.previous = node.previous;
else// node is tail
tail = node.previous;
node.next = head;
head.previous = node;
node.previous = null;
head = node;



}
data = cache_obj.data;
}

return data;
}

public void clear()
{
head = null;
tail = null;
size = 0;
map.clear();
}

public int size()
{
return this.size;
}

public int getCapacity()
{
return this.capacity;
}

/**
*
* for debug
*/

public void printFrontTrace()
{

//print front from head to tail
if(head!=null)
{
KeyNode node = head;
while(node!=null)
{
System.out.print("-->"+node.key+"["+map.get(node.key).data+"]");
node=node.next;
}
}

}

public void printBackwardTrace()
{
if(tail!=null)
{
KeyNode node = tail;
while(node!=null)
{
System.out.print("<--"+node.key+"["+map.get(node.key).data+"]");
node=node.previous;
}
}
}

/****************************inner class from object store**************************************/

class KeyNode
{

KeyNode previous;
KeyNode next;
Object key;

public KeyNode(Object key)
{
this.key = key;
}

}


class CacheObject
{
public CacheObject(KeyNode node,Object data)
{
keyNode = node;
this.data = data;
}
KeyNode keyNode;
Object data;

}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值