2011-10-12 70 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 - 这就是我想表达的。我会修改措辞。 –