Scala 集合包含相同的元素,但 sameElements() 返回 false [英] Scala Sets contain the same elements, but sameElements() returns false

查看:104
本文介绍了Scala 集合包含相同的元素,但 sameElements() 返回 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 Iterables (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆