为番石榴缓存选择密钥

时间:2014-03-12 15:03:24

标签: java caching key guava

我是Guava缓存的新手并寻找一些建议。

我想缓存"功能" - 负责某些计算的班级。每个类有3个双重属性:start,max,increment

创建用于存储在缓存中的密钥的最佳方法是什么?复杂的对象怎么样?

我正在考虑使用Hasher,但对于复杂的对象,相同的哈希并不意味着相同的对象。所以关键 - >价值不会是唯一的。

另外,Cache如何查找密钥? 我注意到如果我使用2个对象传递等于的密钥,则Cache认为它是唯一密钥。它是否基于key1 == key2工作?

public static void testGuavaCache() {
    Cache<Object, String> CACHE = CacheBuilder.newBuilder().weakKeys().weakValues().build();

    for (int i = 0; i < 2; i++) {
        Joiner joiner = Joiner.on('|');
        String key1 = joiner.join(i, i, i, i, i, i, i);

        for (int j = 0; j < 2; j++) {
            String key = joiner.join(i, i, i, i, i, i, i);
            System.out.println(key1.equals(key));
            System.out.println(key1 == key);
            try {
                String m = CACHE.get(key, new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        return "test";
                    }
                });

                System.out.println("Size = " + CACHE.size());

            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

输出是:

true
false
Size = 1
true
false
Size = 2
true
false
Size = 3
true
false
Size = 4

删除weakKeys()解决了这个问题。这是预期的吗?

2 个答案:

答案 0 :(得分:2)

阅读weakKeys的文档:

  

警告:使用此方法时,生成的缓存将使用标识(==)比较来确定密钥的相等性。

所以是的,你应该停止使用weakKeys,而你也可能最好拥有一个合适的价值对象,而不是将事物连接成一个String

答案 1 :(得分:-1)

如果参数是String,则使用分隔符连接函数的所有参数。这将唯一地定义结果。如果参数是数字或两者的组合,您可以将它们编码为ByteBuffer并使用它的hashCode作为保存内存的键。如果参数数据很大(可能是+32字节),您可以使用摘要算法(如MD5)对密钥进行编码,并将结果用作密钥。在这种情况下,您需要权衡生成摘要的处理成本,而不是计算缓存结果。