DNA*_*DNA 53 scala scala-collections
在Iterables上完成Scala 练习时,我遇到了以下奇怪的行为:
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?!
Run Code Online (Sandbox Code Playgroud)
当然这些集合具有相同的元素,应该忽略排序; 为什么这只能用于更大的集合?
DNA*_*DNA 94
Scala集合库为少于5个值的集合提供专门的实现(请参阅源代码).这些实现的迭代器按照添加顺序返回元素,而不是用于较大集合的基于哈希的一致排序.
此外,sameElements(scaladoc)在Iterables 上定义(它实现在IterableLike- 参见源代码); 仅当迭代器以相同的顺序返回相同的元素时,它才返回true.
因此虽然Set(1,2,3)并且Set(3,2,1) 应该是等价的,但它们的迭代器是不同的,因此sameElements返回false.
这种行为是令人惊讶的,并且可以说是一个错误,因为它违反了Set的数学期望(但仅限于某些大小的Set!).
正如IK在评论中指出的那样,==如果你只是将集合相互比较,那么工作正常,即Set(1,2,3) == Set(3,2,1).但是,sameElements更通用,因为它可以比较任何两个iterables的元素.例如,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)
Run Code Online (Sandbox Code Playgroud)
我已经为Scala练习提交了一个解释问题的修复程序.sameElements