2012-04-19 15 views
1

我有一個非常大的不可變對象Set,所以我正在考慮在構建時爲它們分配一個唯一的哈希碼。Java:通過靜態計數器在不可變對象上的唯一hashCode()

private static int counter = Integer.MIN_VALUE; 

private final double foo; 
private final double bar; 
private final int hashCode; 

public MyImmutableObject(double foo, double bar) 
{ 
    counter++; 
    this.foo = foo; 
    this.bar = bar; 
    this.hashCode = counter; 
} 

@Override 
public int hashCode() 
{ 
    return this.hashCode; 
} 

    /** 
    * Unneeded override of equals since its the same as in 
    * Object, but shown for demonstration purposes. 
    */ 
@Override 
public boolean equals(final Object obj) 
{ 
    return this == obj; 
} 

這樣一來,我可以實現按鍵的儘可能高的分散性,因爲我將有2 唯一的密鑰。當然,這也意味着這種類型的任何對象都不會是平等的,因爲一個對象只會等於它自己。

編輯:對象也用作Map s中的鍵。

這可能嗎?我錯過了隱藏的陷阱嗎?

回答

4

這可能嗎?我錯過了隱藏的陷阱嗎?

線程安全,一方面?當然,你可以用AtomicInteger來解決這個問題。

然後,它也是毫無意義的,真的。內置哈希代碼是非常接近獨特,沒有你做任何額外的工作(並採取額外的4個字節每個對象)。鑑於你沒有改變平等的含義(它仍然基本上是參考平等),我看不出有什麼好的理由來做到這一點。

+1

即使使用完全獨特的散列碼,散列表仍然會發生衝突 - 因爲您基本上是通過某種值修改散列碼。沒有完美的方法來避免碰撞,甚至不是OP描述的方式。鑑於此,爲什麼增加額外的複雜性? – 2012-04-19 19:26:39

+0

我總是用番石榴的Objects.hashCode()創建hashCodes,我假設我碰到了一些衝突,因爲我注意到在使用Set/Map的這些對象的過程中大約有20%的改進。根據我的測試和分析,未緩存該值會顯着降低性能。 – 2012-04-19 19:28:05

+0

@AlexanderKaratarakis:我並不是在建議使用'Objects.hashCode' - 因爲在平等測試中沒有涉及任何字段,所以不知道你會在這裏散列什麼。我建議完全刪除'hashCode'和'equals'。只需使用內置的實現,因爲您只需查找參考平等。 – 2012-04-19 19:30:29

相關問題