为什么 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.