Scala 集合包含相同的元素,但 sameElements() 返回 false [英] Scala Sets contain the same elements, but sameElements() returns false
问题描述
在使用 Scala Iterables 练习 时,我遇到了以下奇怪的行为:
Whilst working through the Scala exercises on Iterables, I encountered the following strange behaviour:
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?!
当然这些集合具有相同的元素,应该忽略排序;为什么这仅适用于更大的集合?
Surely these Sets have the same elements, and should ignore ordering; and why does this work as expected only for the larger set?
推荐答案
Scala 集合库为少于 5 个值的集合提供专门的实现(请参阅 源).这些实现的迭代器按照元素添加的顺序返回元素,而不是用于较大集合的一致的、基于哈希的排序.
The Scala collections library provides specialised implementations for Sets of fewer than 5 values (see the source). The iterators for these implementations return elements in the order in which they were added, rather than the consistent, hash-based ordering used for larger Sets.
此外,sameElements
(scaladoc) 在 Iterable
上定义(它在 IterableLike中实现)代码> - 请参阅源);仅当迭代器以相同的顺序返回相同的元素时,它才返回 true.
Furthermore, sameElements
(scaladoc) is defined on Iterable
s (it is implemented in IterableLike
- see the source); it returns true only if the iterators return the same elements in the same order.
所以尽管 Set(1,2,3)
和 Set(3,2,1)
应该是等价的,但它们的迭代器不同,因此 sameElements
返回 false.
So although Set(1,2,3)
and Set(3,2,1)
ought to be equivalent, their iterators are different, therefore sameElements
returns false.
这种行为令人惊讶,可以说是一个错误,因为它违反了对 Set 的数学期望(但仅限于某些大小的 Set!).
This behaviour is surprising, and arguably a bug since it violates the mathematical expectations for a Set (but only for certain sizes of Set!).
作为 I.K.在评论中指出, ==
如果您只是将 Sets 相互比较,则效果很好,即 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)
是真的.
As I.K. points out in the comments, ==
works fine if you are just comparing Sets with one another, i.e. Set(1,2,3) == Set(3,2,1)
. However, sameElements is more general in that it can compare the elements of any two iterables. For example, List(1, 2, 3) == Array(1, 2, 3)
is false, but List(1, 2, 3) sameElements Array(1, 2, 3)
is true.
更一般地说,平等可能会令人困惑 - 请注意:
More generally, equality can be confusing - note that:
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)
我已为Scala 练习,解释了 sameElements
问题.
I have submitted a fix for the Scala exercises that explains the sameElements
problem.
这篇关于Scala 集合包含相同的元素,但 sameElements() 返回 false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!