您的位置:首页 > 编程语言 > Java开发

java实现简单的LRU Cache

2014-09-22 23:03 369 查看
题目来源https://oj.leetcode.com/problems/lru-cache/

我第一次的实现思路是为每个键值对记录下访问时间,然后删除时遍历访问时间来删除,显然这样的效率不高

public class LRUCache {

private int cap;
private HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
private HashMap<Integer,Long> tmap = new HashMap<Integer,Long>();
public LRUCache(int capacity) {
this.cap = capacity;
}

public int get(int key) {
Integer i = map.get(key);
if(i == null)
return -1;
else
{
tmap.put(key,System.nanoTime());
return i;
}
}

public void set(int key, int value) {
map.put(key,value);
tmap.put(key,System.nanoTime());
if(map.size() > this.cap)
{
long oldvalue = Long.MAX_VALUE;
int oldkey = -1;
for(Map.Entry<Integer,Long> en : tmap.entrySet())
{
if(en.getValue() < oldvalue)
{
oldvalue = en.getValue();
oldkey = en.getKey();
}
}
map.remove(oldkey);
tmap.remove(oldkey);
}
}
}


看了网上的讨论,用双向链表来维护访问的顺序比较好,于是给出下面的实现

class LRUCache {

private int cap;
private HashMap<Integer,Item> map = new HashMap<Integer,Item>();
private Item sen;
public LRUCache(int capacity) {
this.cap = capacity;
sen = new Item(null,null);
sen.pre = sen;
sen.next = sen;
}
static class Item
{
public Item(Integer k, Integer v)
{
this.key = k;
this.value = v;
}
public Integer key;
public Integer value;
public Item pre;
public Item next;

}
private void removeItem(Item i)
{
i.pre.next = i.next;
i.next.pre = i.pre;
}
private void insertItem(Item i)
{
i.next = sen.next;
sen.next.pre = i;
i.pre = sen;
sen.next = i;
}
private void movetoHead(Item i)
{
removeItem(i);
insertItem(i);
}
public int get(int key) {
Item i = map.get(key);
if(i == null)
return -1;
else
{
movetoHead(i);
return i.value;
}
}

public void set(int key, int value) {
Item i = map.get(key);
if(i == null)
{
i = new Item(key,value);
map.put(key, i);
insertItem(i);
}
else
{
i.value = value;
movetoHead(i);
}
if(map.size() > this.cap)
{
Item re = sen.pre;
removeItem(re);
map.remove(re.key);

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java map