集合库对相等和哈希处理采取了统一的方法。首先,将集合划分为集合、映射和序列。不同类别的集合始终不相等。例如,Set(1, 2, 3)
与 List(1, 2, 3)
不相等,即使它们包含相同的元素。另一方面,在同一类别中,当且仅当集合具有相同的元素(对于序列:相同元素按相同顺序排列)时,集合才相等。例如,List(1, 2, 3) == Vector(1, 2, 3)
,并且 HashSet(1, 2) == TreeSet(2, 1)
。
对于相等性检查,集合是可变的还是不可变的并不重要。对于可变集合,在执行相等性测试时,只需考虑其当前元素。这意味着可变集合在不同时间可能等于不同的集合,具体取决于添加或删除了哪些元素。当在哈希映射中将可变集合用作键时,这是一个潜在的陷阱。示例
scala> import collection.mutable.{HashMap, ArrayBuffer}
import collection.mutable.{HashMap, ArrayBuffer}
scala> val buf = ArrayBuffer(1, 2, 3)
val buf: scala.collection.mutable.ArrayBuffer[Int] =
ArrayBuffer(1, 2, 3)
scala> val map = HashMap(buf -> 3)
val map: scala.collection.mutable.HashMap[scala.collection.
mutable.ArrayBuffer[Int],Int] = Map((ArrayBuffer(1, 2, 3),3))
scala> map(buf)
val res13: Int = 3
scala> buf(0) += 1
scala> map(buf)
java.util.NoSuchElementException: key not found:
ArrayBuffer(2, 2, 3)
在此示例中,最后一行中的选择很可能会失败,因为数组 buf
的哈希代码已在倒数第二行中更改。因此,基于哈希代码的查找将查看 buf
存储位置之外的位置。