Scala集包含相同的元素,但sameElements()返回false

时间:2015-03-12 11:25:53

标签: scala scala-collections

在使用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?!

当然这些集合具有相同的元素,应该忽略排序;为什么这只能用于较大的集合?

1 个答案:

答案 0 :(得分:91)

Scala集合库为少于5个值的集合提供专门的实现(请参阅source)。这些实现的迭代器按照添加它们的顺序返回元素,而不是用于较大集合的基于哈希的一致排序。

此外,sameElementsscaladoc)已在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更通用,因为它可以比较任何两个iterables的元素。例如,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问题。