単純に、キーを取得するときに一部のフィールド(タイムスタンプ、メッセージIDなど)を考慮すべきではないため、キャッシュが正しいキーを選択する方法をオーバーライドする必要があります。
キーオブジェクトの実際のハッシュ関数は、コードでの認識にすでに使用されているため、変更できません。
Guavaキャッシュで可能ですか?そして回避策はありますか?
これは私の構成です:
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();
}
});
そしてこれは私のハッシュ関数です(私のコードのどこかで使用されています):
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;
}
ところで、この種のキャッシュは、独自のハッシュ関数の実装を使用していますか(たとえば、イントロスペクションによる)、それともデフォルトのキャッシュを使用していますか?
**編集: **
応答で指摘されているように、この結果を達成するための最良の方法はラッパークラスです。
私の解決策:
/**
* 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()
// ...
}
}