[英]Using UUIDs for cheap equals() and hashCode()
我有一個不可變的類TokenList,它由Token對象列表組成,它們也是不可變的:
@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;
}
}
我對這些TokenLists執行了幾個操作,這些操作將多個TokenLists作為輸入並返回單個TokenList作為輸出。 可以有任意多個TokenLists進入,每個TokenLists可以有任意多個Tokens。
這些操作很昂貴,並且很有可能多次執行相同的操作(即相同的輸入),所以我想緩存輸出。 但是,性能至關重要,我擔心在這些可能包含任意多個元素的對象上執行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,我可能在任何時候最多有大約1,000,000個TokenList對象在應用程序中活動。 鑒於此,以及UUID在緩存鍵中組合使用的事實,似乎產生錯誤結果的可能性非常小。 盡管如此,我對它的進展感到不安,因為它感覺“很臟”。 有什么理由我不應該使用這個系統嗎? UUID.randomUUID()使用的SecureRandom的性能成本是否會超過收益(特別是因為我希望多個線程同時執行此操作)? 碰撞是否比我想象的更可能? 基本上,這樣做有什么不妥嗎?
謝謝。
你正在嘗試的是非常棘手的,需要詳細的分析。 因此,在決定采用任何方法之前,您需要檢查以下問題。
這些操作很昂貴,並且很有可能多次執行相同的操作(即相同的輸入)
1)當您在上面的行中說“相同輸入”時,您的意思是什么? 這是否意味着,完全相同的對象,即通過多個引用(相同的內存位置)引用的一個對象,或者它是指內存方式分離的對象,但邏輯上具有相同的數據?
這里如果對象是相同的,即相同的內存位置,那么==比較就可以了。 為此,您必須將對象引用保留為緩存中的鍵。
但如果它是第二種情況,即內存方式單獨的對象,但在邏輯上相同,那么我不認為UUID會幫助你。 因為您必須確保這兩個單獨的對象將獲得相同的UUID。 這將是不容易的,因為無論如何你必須通過整個TokenList數據來確保這一點
2)在緩存中使用哈希碼,是否安全? 我建議不要使用hashcode作為密鑰,因為即使2個對象不同,它們也可能具有相同的哈希碼。 所以你的邏輯可能會出錯。
因此,首先要明確這些問題的答案,然后才考慮方法。
SecureRandom
不會給你任何提升,它比普通Random
“更”隨機。 碰撞的可能性是數字平方除以總可能的UUID的順序,因此數量非常小。 不過,我不會依賴這個數字總是獨一無二的。 您可以嘗試這樣做,但最好檢查並確保該數字尚未包含在哈希碼列表中的其他位置。 否則,你可能會遇到一些非常奇怪的問題......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.