【发布时间】:2015-02-13 01:29:33
【问题描述】:
我试图使用 LinkedHashMap 实现 LRU 缓存。 在 LinkedHashMap (http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html) 的文档中,它说:
请注意,如果将键重新插入到地图中,插入顺序不会受到影响。
但是当我执行以下操作时
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private int size;
public static void main(String[] args) {
LRUCache<Integer, Integer> cache = LRUCache.newInstance(2);
cache.put(1, 1);
cache.put(2, 2);
cache.put(1, 1);
cache.put(3, 3);
System.out.println(cache);
}
private LRUCache(int size) {
super(size, 0.75f, true);
this.size = size;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > size;
}
public static <K, V> LRUCache<K, V> newInstance(int size) {
return new LRUCache<K, V>(size);
}
}
输出是
{1=1, 3=3}
这表明重新插入确实影响了订单。 有人知道解释吗?
【问题讨论】:
-
我想知道,您这样做是为了特定目的吗?因为Java 已经提供了一个
WeakHashMap,它提供了这个功能。 docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html -
如果重新插入不影响订单。顺序应该是 {2=2, 3=3},因为 {1=1} 先添加并重新插入。
-
@Jack
WeakHashMap不会像你 think it does 那样做。它与LRU cache 不同。 -
@Jeffrey:它完全符合我的想法。它提供了一种数据结构,允许存储缓存的值,而不必担心如果它们没有在代码中的其他任何地方引用,它们就会被清除。这是一种实现 LRU 缓存的垃圾收集方式。如果您不需要擦除旧值(用于刷新问题,这就是我所说的特定目的),那么它通过允许 Java 在出现时释放它们来解决这个问题是必须的。
-
@Jack 我正在实现这个以进行编码练习。如果我使用 LRU 来保存临时对象并让 GC 处理所有事情,我认为使用 weakHashMap 是一种更好的方法。谢谢
标签: java insert linkedhashmap lru