是否存在Guava的Cache
和Multimap
功能的组合?本质上,我需要一个集合,在其中条目在给定时间后过期,例如在Cache
中可用,但我有非唯一键,并且我需要条目独立地过期。
我认为Louis Wasserman在上面的评论中已经给出了答案,即没有现成的Multimap
和Cache
组合可用。我通过下面的伪代码概述的解决方案解决了我的问题/需求:
private Cache<Integer,Object> cache = CacheBuilder.newBuilder().SomeConfig.build();
private Multimap<Integer,Object> multimap = HashMultimap<Integer, Object>.create();
private AtomicInteger atomicid = new AtomicInteger(0);
public void putInMultimap(int id, Object obj) {
int mapid = atomicid.addAndGet(1);
cache.put(mapid,obj);
multimap.put(id,mapid);
}
public List<Object> getFromMultimap(int id) {
Set<Integer> mapids = multimap.get(id);
List<Object> list = new ArrayList<Object>();
for (int i : mapids) {
list.add(cache.getIfPresent(i));
}
return list;
}
这个简单的“解决方案”有一些限制,但对我来说还可以。
使用Guava Cache时没有put方法,缓存是设计为自动填充的。从键查找返回的值在运行时计算。Commons Collections Transformer Factories采用了类似的方法。
我认为你可以很容易地实现你要寻找的内容。如果你看一个简单的Map支持示例,比如Kitty-Cache,你会发现你可以用Multimap替换Map并相应地重写其他方法。所以在KittyCache.java内部,你可以有这样的东西:
Multimap<K, CacheEntry<V>> cache;
put
方法,该缓存被设计成可自行填充。事实上,Cache
本身没有put
方法,而LoadingCache
则是被设计为自行填充的,但您仍然可以使用非加载缓存,并调用cache.asMap().put(...)
来添加自己的条目。当然,这不能让您获得多重映射。只是更正了第一个陈述。 - RayCache
中有一个[put方法](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#put(K, V))。您提供的示例很有趣,但我不能依赖于请求过期,我实现了RemovalListener
来获取在Cache
中过期时的通知。 - hgus1294put
是在11.0版本中添加的。我的错误。 - RayMultimap
实现非常复杂,我们的内部实现不适用于处理缓存条目过期。这将是一个相当重要的项目。 =/ - Louis WassermanCache
而不是 LoadingCache
,你就可以将 Cache.asMap()
视图传递到 Multimaps.newMultimap
中。Cache.asMap()
传递给了Multimaps.newMultimap
,并使用expireAfterWrite
设置为1000毫秒进行了一些快速测试,并运行了以下场景:map.put(1,Object1);
Thread.Sleep(700)
map.put(1,Object2);
Thread.Sleep(500)
。此时,我希望第一个条目被驱逐,但第二个条目仍然存在,但我发现两个条目都被驱逐了。也许我做错了什么,但除非我能改变这种行为,否则它对我没有用。 - hgus1294
SomeConfig
部分,您可以在那里添加一个.removalListener
调用,每当从缓存中驱逐某些内容时都会调用它,以便您还可以将其从 multimap 中删除。 - Philipp Gayret