使用scala.util.Random在Set vs List上进行shuffle的行为

k r*_*k r 11 random scala shuffle list set

 scala> Random.shuffle((1 to 10).toSet)
 res10: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)

 scala> Random.shuffle((1 to 10).toSet)
 res11: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)

 scala> Random.shuffle((1 to 10).toSet)
 res12: scala.collection.immutable.Set[Int] = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)

 scala> Random.shuffle((1 to 10).toList)
 res13: List[Int] = List(3, 9, 8, 5, 7, 6, 10, 2, 1, 4)

 scala> Random.shuffle((1 to 10).toList)
 res14: List[Int] = List(5, 10, 2, 9, 4, 7, 8, 6, 1, 3)

 scala> Random.shuffle((1 to 10).toList)
 res15: List[Int] = List(5, 9, 10, 6, 8, 3, 4, 1, 7, 2)
Run Code Online (Sandbox Code Playgroud)

所以shuffle可以处理Lists就好了,但没有设置?洗不了套?为什么res10 == res11 == res12?

Tra*_*own 20

Scala的集合没有排序(就像数学集合一样).它们是可迭代的,但是你不能依赖于你将获得项目的顺序.许多集合的实现将以相同的顺序迭代相同的元素 - 即,

scala> Set(1, 2, 3, 4, 5).toList == Set(5, 4, 3, 2, 1).toList
res0: Boolean = true
Run Code Online (Sandbox Code Playgroud)

这解释了你在这里看到的效果.你应该永远不要依赖于此 - 可能有一个完美的有效Set实现,而上述情况并不成立.

  • 这有点奇怪,我不确定为什么`shuffle`被定义为任何`TraversableOnce`(而不是说'Seq`).根本不可能为可以提供随机顺序的集合编写`shuffle`版本,因为谈论集合的_any_种顺序是没有意义的. (7认同)
  • 刚刚看到你的评论编辑:是的,但是`shuffle`会返回一个与其输入相同类型的集合,只要你将洗牌后的列表放回到一个集合中,就会陷入相同的情况. (2认同)