不変の Token オブジェクトのリストで構成される TokenList という不変のクラスがあります。これも不変です。
@Immutable
public final class TokenList {
private final List<Token> tokens;
public TokenList(List<Token> tokens) {
this.tokens = Collections.unmodifiableList(new ArrayList(tokens));
}
public List<Token> getTokens() {
return tokens;
}
}
これらの TokenList に対して、複数の TokenList を入力として取り、単一の TokenList を出力として返す操作をいくつか実行します。任意の数の TokenList が入る可能性があり、それぞれが任意の数の Token を持つことができます。
これらの操作はコストが高く、同じ操作 (つまり、同じ入力) が複数回実行される可能性が高いため、出力をキャッシュしたいと考えています。ただし、パフォーマンスは重要であり、任意の数の要素を含む可能性のあるこれらのオブジェクトに対して hashCode() および equals() を実行する費用が心配です (これらは不変であるため、hashCode をキャッシュできますが、equals は依然として高価です)。
これにより、TokenList に次の更新を行うことで、UUID を使用して equals() と hashCode() を簡単かつ安価に提供できるかどうか疑問に思いました。
@Immutable
public final class TokenList {
private final List<Token> tokens;
private final UUID uuid;
public TokenList(List<Token> tokens) {
this.tokens = Collections.unmodifiableList(new ArrayList(tokens));
this.uuid = UUID.randomUUID();
}
public List<Token> getTokens() {
return tokens;
}
public UUID getUuid() {
return uuid;
}
}
そして、キャッシュキーとして機能する次のようなもの:
@Immutable
public final class TopicListCacheKey {
private final UUID[] uuids;
public TopicListCacheKey(TopicList... topicLists) {
uuids = new UUID[topicLists.length];
for (int i = 0; i < uuids.length; i++) {
uuids[i] = topicLists[i].getUuid();
}
}
@Override
public int hashCode() {
return Arrays.hashCode(uuids);
}
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (other instanceof TopicListCacheKey)
return Arrays.equals(uuids, ((TopicListCacheKey) other).uuids);
return false;
}
}
私は 2^128 の異なる UUID があり、アプリケーション内でアクティブな TokenList オブジェクトが常に最大で約 1,000,000 あると考えています。これと、UUID がキャッシュ キーで組み合わせて使用されるという事実を考えると、これが間違った結果を生み出す可能性はほとんどないように思われます。とはいえ、「汚い」と感じるだけで先に進むのは不安です。このシステムを使用してはいけない理由はありますか? UUID.randomUUID() によって使用される SecureRandom のパフォーマンス コストは、利益を上回りますか (特に、複数のスレッドが同時にこれを実行すると予想されるため)。衝突は私が思っているよりも起こりそうですか? 基本的に、このようにすると何か問題がありますか??
ありがとう。