有限大小的哈希映射

时间:2012-09-07 14:06:56

标签: java

我想将哈希映射用作缓存。 缓存具有初始大小,如果您尝试在缓存已满时插入项目,则最近使用的项目应该被替换...任何想法?

6 个答案:

答案 0 :(得分:16)

您可以通过实施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

答案 1 :(得分:8)

你看过Guava了吗?它具有基于工厂的方法,用于创建具有caches等的集合。

e.g。 (来自链接文章)

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);
         }
       });

答案 2 :(得分:2)

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

答案 3 :(得分:1)

从Apache Commons查看LRUMap

  

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

     

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

     

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

     

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

     

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

答案 4 :(得分:1)

您可以将绑定队列与哈希映射一起保留。通过这种方式,您可以轻松地知道哪个项目是最旧的。

答案 5 :(得分:0)

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