插入密钥时自定义等于/ hash(Guava Cache)

Ham*_*000 8 java hash equals guava

简单地说,我必须覆盖缓存选择正确密钥的方式,因为在检索密钥时不应考虑某些字段(例如,时间戳,消息ID等). 我无法修改密钥对象的实际哈希函数,因为它已经用于在我的代码中识别.
是否可以使用番石榴缓存?有一个解决方法?

这是我的配置:

CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).recordStats().
    expireAfterWrite(DEFAULT_AGE, TimeUnit.DAYS).build(
    new CacheLoader<Request, Response>() {
        @Override
        public Response load(Request request) { 
            return request.getResponse();
        }
    });
Run Code Online (Sandbox Code Playgroud)

这是我的哈希函数(在我的代码中的其他地方使用):

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + code;
    result = prime * result + messageID; // <= **this one shouldn't evaluated**
    result = prime * result + Arrays.hashCode(payload);
    result = prime * result + (int) (timestamp ^ timestamp >>> 32); // <= **this one shouldn't evaluated**
    result = prime * result + (type == null ? 0 : type.hashCode());
    result = prime * result + version;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这种缓存是使用自己的哈希函数实现(例如,通过内省)还是使用默认的缓存?

**编辑:**
正如响应中指出的,实现此结果的最佳方法是包装类.
我的解决方案:

/**
 * Nested class to store a request as a key in the cache. It is needed to
 * normalize the variable fields of the normal requests.
 */
private static final class CachedRequest extends Request {

    private static CachedRequest fromRequest(Request request) {
        // set only the fields that cannot change between two same requests
        // ...
    }

    @Override
    public int hashCode() {
        HashFunction hashFunction = Hashing.md5();
        HashCode hashCode;
        // ...
        return hashCode.asInt();
    }

    @Override
    public boolean equals(Object obj) {
            // coherent with hashCode()
            // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 15

您可以简单地将Request对象包装到CachedRequest对象中,在对象中CachedRequest实现hashCode()equals()基于所需的字段,并提供对包装的访问Request.