Scala 集合包含相同的元素,但 sameElements() returns false

Scala Sets contain the same elements, but sameElements() returns false

在使用 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 个值的集合提供专门的实现(参见 source)。这些实现的迭代器 return 元素 按照它们添加的顺序 ,而不是用于较大集合的一致的、基于散列的排序。

此外,sameElements (scaladoc) is defined on Iterables (it is implemented in IterableLike - see the source);它 return 仅当迭代器 return 以相同顺序排列相同元素时才为真。

所以虽然Set(1,2,3)Set(3,2,1)应该是等价的,但是他们的迭代器是不同的,所以sameElementsreturns假的。

这种行为令人惊讶,并且可以说是一个错误,因为它违反了 Set 的数学期望(但仅适用于某些大小的 Set!)。

如I.K。在评论中指出,如果您只是将集合相互比较,== 就可以正常工作,即 Set(1,2,3) == Set(3,2,1)。但是,sameElements 更通用,因为它可以比较任意两个可迭代对象的元素。例如,List(1, 2, 3) == Array(1, 2, 3) 为假,但 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 for the Scala exercises 可以解释 sameElements 问题。