使用 scala.util.Random 在 Set vs List 上的随机播放行为


 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)

所以洗牌可以很好地处理列表,但不能处理集合?集合不能洗牌吗?为什么 res10 == res11 == res12 ?

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

scala> Set(1, 2, 3, 4, 5).toList == Set(5, 4, 3, 2, 1).toList
res0: Boolean = true

这就解释了你在这里看到的效果。但是,您永远不应该依赖这一点 - 可能有一个完美的有效Set实现,而上述实现则不成立。

Random 正在"洗牌"集合;它只是没有可见的效果,因为集合没有顺序。REPL 碰巧每次都以相同的方式打印随机播放集:

scala> Set(1,2,3,4,5) 
res29: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
scala> Set(5,4,3,2,1)
res30: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
scala> util.Random.shuffle(res30)
res31: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

最新更新