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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29008500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 06:57:32  来源:igfitidea点击:

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

scalascala-collections

提问by DNA

Whilst working through the Scala exercises on Iterables, I encountered the following strange behaviour:

对 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?!

Surely these Sets have the same elements, and should ignore ordering; and why does this work as expected only for the larger set?

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

回答by DNA

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.

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

Furthermore, sameElements(scaladoc) is defined on Iterables (it is implemented in IterableLike- see the source); it returns true only if the iterators return the same elements in the same order.

此外,sameElements( scaladoc) 是在Iterables上定义的(它是在IterableLike- 参见源代码中实现的);只有当迭代器以相同的顺序返回相同的元素时,它才返回真。

So although Set(1,2,3)and Set(3,2,1)oughtto be equivalent, their iterators are different, therefore sameElementsreturns false.

所以虽然Set(1,2,3)Set(3,2,1)应该是等价的,但它们的迭代器是不同的,因此sameElements返回 false。

This behaviour is surprising, and arguably a bug since it violates the mathematical expectations for a Set (but only for certain sizes of Set!).

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

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.

正如 IK 在评论中指出的那样,==如果您只是将 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)是真的。

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)

I have submitted a fixfor the Scala exercisesthat explains the sameElementsproblem.

我已经提交了解释问题的Scala 练习的修复程序sameElements