【问题标题】:Sort Order for Scala Set and shufflingScala Set 和 shuffle 的排序顺序
【发布时间】:2015-05-15 19:35:59
【问题描述】:
scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.

scala> 300 to 1000 toSet
warning: there were 1 feature warning(s); re-run with -feature for details
res0: scala.collection.immutable.Set[Int] = Set(645, 892, 809, ...)

// 问题#1:我预计再次运行时顺序会有所不同。它与 res0 的顺序相同。 所以我想,可能是由于不同的原因(系统熵等),范围太小而无法区分。

scala> 300 to 1000 toSet
warning: there were 1 feature warning(s); re-run with -feature for details
res1: scala.collection.immutable.Set[Int] = Set(645, 892, 809, ...)

// 问题#2:这太奇怪了。即使在洗牌后,我也看到了相同的顺序。为什么?

scala> scala.util.Random.shuffle((300 to 1000).toSet)
res2: scala.collection.immutable.Set[Int] = Set(645, 892, 809, ...)

【问题讨论】:

    标签: scala set shuffle


    【解决方案1】:

    scala 中的标准不可变 Set 被实现为 Hash Tries。它基本上是一棵树,它使用添加到它的值的哈希码。这就是它有效检测Set中已经存在的值的方式。

    因为无论添加到集合中的顺序如何,添加的值的哈希码都是相同的,所以Set 始终处于相同的顺序是合理的。当然,需要注意的是,这种顺序既不是外部确定的,也不是保证的。因此,即使您喜欢 Set 的顺序,也不能保证它不会在编译器或 JVM 的任何版本中发生变化

    【讨论】:

      【解决方案2】:

      普通的Sets 不保证任何订单。这意味着它可以选择以它认为最有效或最方便的任何顺序存储数据。

      它可能会选择以不同的顺序存储,具体取决于向它提供或不提供物品的顺序。它不做任何保证。

      重要的是,如果它碰巧在一个版本的 scala 中这样做,则取决于此特定结果将是危险的,因为没有明确的保证。

      所以,我不知道它为什么选择得到这个结果,但结果实际上是任意的,你不能依赖它。洗牌Set 没有具体价值,因为Set 可以选择以它选择的任何顺序存储它们。

      如果您需要在Set 中排序,则选择TreeSetSortedSet,它们可以保证返回元素的顺序。

      其他对 scala 中的 Set 实现的内部有更多了解的人可能会就实现的细节提供更详细的答案。

      据我了解,默认的不可变 SetHashSet 实现,因此,对于任何给定的 Set 值,无论插入的顺序如何,存储桶都不太可能发生变化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-10
        • 1970-01-01
        • 2016-10-19
        • 2018-09-29
        • 1970-01-01
        • 1970-01-01
        • 2012-05-31
        相关资源
        最近更新 更多