为什么 Stream.distinct 不明显?
Why is Stream.distinct not distinct?
我正在尝试以下代码,很惊讶地发现了重复项。我认为 Stream.distinct
只会 return 不同的值。我在这里做错了什么?
import scala.collection.mutable
import scala.util.Random.shuffle
object DistinctStreamTest {
def rand(): Stream[Int] = Stream.cons(shuffle(1 to 1000).head, rand()).distinct
def main(args: Array[String]): Unit = {
val usedNumbers = mutable.HashSet.empty[String]
(0 to 100).foreach(i => {
val newNumber = rand().take(1).mkString
if (usedNumbers.contains(newNumber)) {
println(s"Found duplicates: $newNumber after $i iterations")
}
usedNumbers += newNumber
})
}
}
您已将 rand()
定义为无限递归 Stream
;因为它不能被物化,所以它不能被分别。
scala> def rand(): Stream[Int] = Stream.cons(shuffle(1 to 1000).head, rand()).distinct
rand: ()Stream[Int]
scala> rand().toList.length
java.lang.WhosebugError
at scala.collection.IndexedSeqLike$Elements.next(IndexedSeqLike.scala:61)
at scala.collection.IterableLike.copyToArray(IterableLike.scala:252)
at scala.collection.IterableLike.copyToArray$(IterableLike.scala:247)
at scala.collection.AbstractIterable.copyToArray(Iterable.scala:54)
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:99)
at scala.util.Random.shuffle(Random.scala:108)
Stream
他们很懒惰,所以从他们那里拿走东西也不会破坏堆栈。
您得到重复项的原因是您将 rand()
定义为 def
。这意味着每次调用都会创建一个新的和不同的 Stream[Int]
。您只是从每个新的 Stream
中获取第一个元素,但重复的可能性非常高。
您可以通过将 rand
改为 val
来修复它,但是您已经递归定义了它,因此尝试访问头部之后的任何内容将导致无限递归。
获取不同值的随机序列的正确方法:
val sq :Seq[Int] = util.Random.shuffle(1 to 1000)
然后访问您可能的值:
(0 to 100).foreach(i => {
val newNumber = sq(i).toString()
... //etc.
我正在尝试以下代码,很惊讶地发现了重复项。我认为 Stream.distinct
只会 return 不同的值。我在这里做错了什么?
import scala.collection.mutable
import scala.util.Random.shuffle
object DistinctStreamTest {
def rand(): Stream[Int] = Stream.cons(shuffle(1 to 1000).head, rand()).distinct
def main(args: Array[String]): Unit = {
val usedNumbers = mutable.HashSet.empty[String]
(0 to 100).foreach(i => {
val newNumber = rand().take(1).mkString
if (usedNumbers.contains(newNumber)) {
println(s"Found duplicates: $newNumber after $i iterations")
}
usedNumbers += newNumber
})
}
}
您已将 rand()
定义为无限递归 Stream
;因为它不能被物化,所以它不能被分别。
scala> def rand(): Stream[Int] = Stream.cons(shuffle(1 to 1000).head, rand()).distinct
rand: ()Stream[Int]
scala> rand().toList.length
java.lang.WhosebugError
at scala.collection.IndexedSeqLike$Elements.next(IndexedSeqLike.scala:61)
at scala.collection.IterableLike.copyToArray(IterableLike.scala:252)
at scala.collection.IterableLike.copyToArray$(IterableLike.scala:247)
at scala.collection.AbstractIterable.copyToArray(Iterable.scala:54)
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:99)
at scala.util.Random.shuffle(Random.scala:108)
Stream
他们很懒惰,所以从他们那里拿走东西也不会破坏堆栈。
您得到重复项的原因是您将 rand()
定义为 def
。这意味着每次调用都会创建一个新的和不同的 Stream[Int]
。您只是从每个新的 Stream
中获取第一个元素,但重复的可能性非常高。
您可以通过将 rand
改为 val
来修复它,但是您已经递归定义了它,因此尝试访问头部之后的任何内容将导致无限递归。
获取不同值的随机序列的正确方法:
val sq :Seq[Int] = util.Random.shuffle(1 to 1000)
然后访问您可能的值:
(0 to 100).foreach(i => {
val newNumber = sq(i).toString()
... //etc.