2011-10-12 95 views
1

假設我們在Scala中有三組字符串。一個有元素A,B,C。兩個元素B,C,D。三有元素J,K,I。Scala Set哈希碼

我的第一個問題是,有沒有什麼辦法可以使這兩個集合中的任何兩個集合的哈希碼相同? 我的第二個問題是,如果我將D添加到One並將A添加到Two以獲得新的集合One.n和Two.n,One.n和Two.n的哈希碼是否相同?

+5

你的問題的一半可以通過使用REPL 3分鐘來回答 –

回答

6

問題1)一般來說,是完全可能的。散列碼的長度是有限的字節數。一個Set可以是任何大小。所以hashcode不可能是唯一的(儘管通常它們是)。

問題2)爲什麼不嘗試?

scala> val One = collection.mutable.Set[String]("A", "B", "C") 
One: scala.collection.mutable.Set[String] = Set(A, B, C) 

scala> One.hashCode 
res3: Int = 1491157345 

scala> val Two = collection.mutable.Set[String]("B", "C", "D") 
Two: scala.collection.mutable.Set[String] = Set(B, D, C) 

scala> Two.hashCode 
res4: Int = -967442916 

scala> One += "D" 
res5: One.type = Set(A, B, D, C) 

scala> Two += "A" 
res6: Two.type = Set(B, D, A, C) 

scala> One.hashCode 
res7: Int = -232075924 

scala> Two.hashCode 
res8: Int = -232075924 

所以,是的,他們是,正如你所期望的,因爲你所期望的==方法是這兩個實例正確的。

+0

在提問之前,我確實嘗試過。我應該說,「...... One.n和Two.n總是一樣嗎?」它仍然不變嗎? – user592419

+3

'hashCode'的規則是:如果你的對象'a','b'報告是相等的,即如果'a.equals(b)',那麼'a.hashCode == b.hashCode'(但不是其他方式)。 – Dirk

+0

@ user592419是的,但你可能不應該依賴它,因爲哈希碼是實現細節而不是指定的公共類成員。例如。有人可能會創建一個覆蓋hashCode方法以返回一個隨機數的子類。 –

2

其中相同且內部沒有任何異常的集合(即任何具有不穩定散列碼或散列碼與等號不一致的地方)應該具有相同的散列碼。如果不是這樣,並且集合是集合的相同類型,則它是一個錯誤並且應該被報告。如果這些集合是不同類型的集合,它可能會或可能不是一個具有不同哈希碼的錯誤(但在任何情況下它應該與equals相等)。但是,我不知道任何不同的集合實現不相等的情況(例如,甚至可變的BitSet都與不可變集合一致)。

所以:

  1. 的hashCode是從未保證是獨一無二的,但應均勻分佈在碰撞的概率應該很低
  2. 的hashCode套應始終與equals一致(只要你放在集合中的所有東西都有hashCode與equals相一致),因爲相等的集合具有相同的散列碼。 (由於第(1)點,反過來不是真的。)
  3. 設置只關心內容的標識,而不是集合的添加順序(這就是有一個集合而不是一個列表)
+0

點2不完全:如果equals爲真,hashcode將只會始終等於equals。等於可能是錯誤的,但hashcode可能是相同的。 –

+0

@LuigiPlinge - 這就是我想表達的。我會修改措辭。 –