Scala Sets 包含相同的元素,但 SameElements() 返回 false

标签 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?!

当然,这些集合具有相同的元素,并且应该忽略排序;为什么这仅适用于较大的集合才能按预期工作?

最佳答案

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/

相关文章:

scala - 如何将域模型设置为参与者?

scala - 使用 Play 控制台中的选项运行 scala 编译器

java - Scala 集合 : util. Map[String, AnyRef] - Map[String, String]

scala - 如何在两个对象列表中找到相同的值scala

scala - Scala的可变Map更新[map(key)= newValue]语法如何工作?

scala - 模式匹配或 Map Monads

Scala 默认参数值派生自以前的参数

scala - Spark : Exception in thread "main" org. apache.spark.sql.catalyst.errors.package

scala - 为什么 TraversableOnce.toSeq 返回一个流?

Scala 的 "This"和 MapLike