在使用 Scala 时 exercises on Iterables ,我遇到了以下奇怪的行为:
val xs = Set(5,4,3,2,1)
val ys = Set(1,2,3,4,5)
xs sameElements ys // true
val xs = Set(3,2,1)
val ys = Set(1,2,3)
xs sameElements ys // false - WAT?!
当然,这些集合具有相同的元素,并且应该忽略排序;为什么这仅适用于较大的集合才能按预期工作?
最佳答案
Scala 集合库为少于 5 个值的 Sets 提供了专门的实现(请参阅 source )。这些实现的迭代器按照元素添加的顺序返回元素,而不是用于较大 Set 的一致的、基于哈希的排序。
此外,sameElements
( scaladoc ) 是在 Iterable
上定义的(它是在 IterableLike
中实现的 - 请参阅 source ) ;仅当迭代器以相同顺序返回相同元素时,它才返回 true。
因此,尽管 Set(1,2,3)
和 Set(3,2,1)
应该 是等价的,但它们的迭代器不同,因此 sameElements
返回 false。
这种行为令人惊讶,并且可以说是一个错误,因为它违反了 Set 的数学期望(但仅限于 Set 的某些大小!)。
正如 I.K.在评论中指出,如果您只是将集合相互比较,则 ==
工作得很好,即 Set(1,2,3) == Set(3,2,1)
。然而,sameElements 更通用,因为它可以比较任意两个可迭代的元素。例如,List(1, 2, 3) == Array(1, 2, 3)
为 false,但 List(1, 2, 3) sameElements Array(1, 2, 3)
是正确的。
更一般地说,平等可能会令人困惑 - 请注意:
List(1,2,3) == Vector(1,2,3)
List(1,2,3) != Set(1,2,3)
List(1,2,3) != Array(1,2,3)
Array(1,2,3) != Array(1,2,3)
我有submitted a fix对于 Scala exercises这解释了 sameElements
问题。
关于Scala Sets 包含相同的元素,但 SameElements() 返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29008500/