使用Java中的LRU驱逐策略缓存一组字符串

时间:2017-03-06 20:49:31

标签: java caching memory guava

我正在尝试以这种方式为一组带有LRU驱逐策略的字符串创建缓存。

private static final Boolean PLACEHOLDER = true;
LoadingCache<String, Boolean> scannedIDsCache = CacheBuilder.newBuilder()
        .build(new CacheLoader<String, Boolean>() {
            @Override
            public Boolean load(String key) throws Exception {
                return PLACEHOLDER;
            }
        });

我认为我只使用一个对象作为所有元素的值来节省空间,我是否正确?你知道其他任何节省空间的方法吗?感谢。

1 个答案:

答案 0 :(得分:6)

不,你没有节省空间。

当JVM * autoboxesboolean调用Boolean.valueOf(boolean)时,会返回Boolean.TRUEBoolean.FALSEstatic final Boolean字段。它不会创建新的Boolean实例。因此,您定义的PLACEHOLDER实际上是对Boolean.TRUE的引用,并且是多余的。

此外,我不会使用Guava的Cache作为LRU,除非我愿意接受这样的事实:“缓存可能会因为最近没有使用或者经常“(CacheBuilder.maximumSize(long)强调已添加)。

如果您想要一个直接的LRU,可以Collections.newSetFromMap(Map)使用LinkedHashMap

Set<String> cache = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>() {
    @Override
    protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) {
        return size() > MAX_ENTRIES;
    }
});

您定义MAX_ENTRIES的位置。

*注意:理论上可能有一些JVM实现在运行时在自动装箱Boolean.valueOf(boolean)原语时不会调用boolean(或类似的东西),但如果存在这样的实现我我非常有信心你没有使用它,而且如果有的话,很少。来自Boolean(boolean)

  

注意:使用此构造函数很少是合适的。除非需要 new 实例,否则静态工厂valueOf(boolean)通常是更好的选择。它可能会产生明显更好的空间和时间性能。