10

我想制作一个哈希映射来像缓存一样使用。缓存有一个初始大小,如果您尝试在缓存已满时插入一个项目,最近使用的项目应该被替换......有什么想法吗?

4

6 回答 6

19

您可以通过实现removeEldest来使用 LinkedHashMap

public static <K,V> Map<K,V> lruCache(final int maxSize) {
    return new LinkedHashMap<K,V>(maxSize*4/3, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
            return size() > maxSize;
        }
    };
}

更多细节

http://vanillajava.blogspot.co.uk/2011/06/java-secret-lru-cache-in-java.html

http://blog.meschberger.ch/2008/10/linkedhashmaps-hidden-features.html

于 2012-09-07T14:09:52.610 回答
8

你看过番石榴吗?它具有基于工厂的方法来创建带有缓存等的集合。

例如(来自链接的文章)

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
   .maximumSize(1000)
   .expireAfterWrite(10, TimeUnit.MINUTES)
   .removalListener(MY_LISTENER)
   .build(
       new CacheLoader<Key, Graph>() {
         public Graph load(Key key) throws AnyException {
           return createExpensiveGraph(key);
         }
       });
于 2012-09-07T14:08:29.107 回答
2

在 Android 上,您可以使用http://developer.android.com/reference/android/util/LruCache.html。我很确定您可以从 AOSP 获取该实现并在 Apache 许可下使用它。

于 2012-09-07T14:10:26.773 回答
1

最简单的方法是扩展LinkedHashMap,覆盖该removeEldestEntry(Map.Entry<K,V> eldest)方法并在其实现中决定您的缓存是否“满”。

于 2012-09-07T14:10:22.670 回答
1

查看来自 Apache Commons的LRUMap 。

具有固定最大大小的 Map 实现,如果在满时添加条目,则删除最近最少使用的条目。

最近最少使用的算法仅适用于 get 和 put 操作。任何类型的迭代,包括通过迭代设置值,都不会改变顺序。containsKey 和 containsValue 等查询或通过视图访问也不会更改顺序。

该地图实现了 OrderedMap,并且可以使用双向 OrderedMapIterator 查询条目。返回的订单是最近最少使用到最近使用的。如果需要,地图视图中的迭代器也可以转换为 OrderedIterator。

通过强制转换为 ResettableIterator 并调用 reset(),可以将所有可用的迭代器重置回起点。

请注意,LRUMap 不是同步的,也不是线程安全的。如果您希望从多个线程同时使用此映射,则必须使用适当的同步。最简单的方法是使用 Collections.synchronizedMap(Map) 包装此地图。当被并发线程访问时,此类可能会抛出 NullPointerException。

于 2012-09-07T14:10:28.990 回答
1

您可以将绑定队列与您的哈希映射一起保留。这样,您将很容易知道哪个项目是最旧的。

于 2012-09-07T14:10:36.487 回答