我想将哈希映射用作缓存。 缓存具有初始大小,如果您尝试在缓存已满时插入项目,则最近使用的项目应该被替换...任何想法?
答案 0 :(得分:16)
您可以通过实施removeEldest
来使用LinkedHashMappublic 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)
方法并在其实施中决定缓存是否“满”。