LeetCode 之 LRU Cache Java实现

  LeetCode刷了41道题了,流程是按照戴兄的小书很多不会的是参考Kim姐的代码,自己用Java抠腚的。

  前几天做到了LRU Cache:

  C++的实现方法大同小异,大都用的是一个list加一个hash,hash中存储list节点地址,每次get从hash中寻key,有则将list相应节点放到链表头,没有则返回-1;每次set先判断hash中是否存在,存在则将相应节点移到表头,重置value值,如果不存在,判定长度是否达到预设的capacity,如果达到,删除表尾节点,新节点插入表头。

  但是用Java如此实现的话就有点绕了,倒是也看到有同学用HashMap和自己定义的双向链表实现的。

  之前用LikedHashMap不是很多,这次就用它实现LRU Cache。LikedHashMap中有一个方法叫removeEldestEntry,作用是判断map中的entry是否超了容量,超了的话会自动删掉最早插入的entry,其实功能已经很接近LRU了,但是不论访问还是set已有的元素,都不会对删除顺序有影响。实现如下:

 

 1 import java.util.LinkedHashMap;
 2 import java.util.Map.Entry;
 3 
 4 /**
 5  * Problem: LRU Cache
 6  * Description: Design and implement a data structure for Least Recently Used
 7  * (LRU) cache. It should support the following operations: get and set.
 8  * get(key) - Get the value (will always be positive) of the key if the key
 9  * exists in the cache, otherwise return -1.
10  * set(key, value) - Set or insert the value if the key is not already present.
11  * When the cache reached its capacity, it should invalidate the least recently
12  * used item before inserting a new item.
13  * Date: Aug 4 , 2014
14  * 
15  * @author Chyace
16  * 
17  */
18 public class LRUCache {
19 // 用来装item的LinkedHashMap子类对象
20     CacheMap cache;
21 
22     public LRUCache(int capacity) {
23         cache = new CacheMap(capacity);
24     }
25 /**
26  * 每次get容器中的值,都将相应元素删除重新插入,这时它就会位于最新的位置
27  * @param key
28  * @return
29  */
30     public int get(int key) {
31         if (cache.containsKey(key)) {
32             int value = cache.get(key);
33             cache.remove(key);
34             set(key, value);
35             return value;
36         }
37         return -1;
38     }
39 
40     public void set(int key, int value) {
41         if (cache.containsKey(key)) cache.remove(key);
42         cache.put(key, value);
43     }
44 }
45 
46 /**
47  * LinkedHashMap只能实现最旧移除而不会更新
48  * 
49  * @author Chyace
50  * 
51  */
52 class CacheMap extends LinkedHashMap<Integer, Integer> {
53 
54     private static final long serialVersionUID = 3240765461462956414L;
55 
56     private int MAX;
57 
58     CacheMap(int max) {
59         this.MAX = max;
60     }
61 
62     protected boolean removeEldestEntry(Entry<Integer, Integer> eldest) {
63         return size() > MAX;
64     }
65 
66 }

 

  最后提交的时候没加import行,编译错,之前用到util的时候都不需要导入,但是这次提交两行都得加,费解……  

  对了,这位仁兄貌似是在工程里实际应用Java 版LRU Cache,很有参考价值。

 

posted @ 2014-08-06 20:08  hyace  阅读(1789)  评论(0编辑  收藏  举报