Scala代码中奇怪的异步/多重现象

Scala代码中奇怪的异步/多重现象,scala,Scala,我的代码: val byDate = data.groupBy(_._1).map(t => t._1 -> t._2.map(_._2).toMap).flatMap { ... } var incomplete: Option[LocalDate] = None val filtered = (incomplete.map { i => println(s"i = $i") byDate.filterKeys { d => println(s"d

我的代码:

val byDate = data.groupBy(_._1).map(t => t._1 -> t._2.map(_._2).toMap).flatMap {
...
}


var incomplete: Option[LocalDate] = None
val filtered = (incomplete.map { i =>
  println(s"i = $i")

  byDate.filterKeys { d =>
    println(s"dd = $d vs i = $i")
  }
}).getOrElse(byDate)
如何理解
(complete.map{})
的功能?从输出来看,我猜它启动了另一个线程?我说得对吗?因为,上述代码的输出被其他输出(在上述程序之后由一些代码打印出来)分隔开

更新

我已经有了一个原因:
filterKeys会延迟执行求值
,因此,只有在使用了
filtered
之后,它才会开始求值。

对Scala集合调用的操作(如map)是顺序执行还是并行执行,取决于集合的类型

默认情况下导入的集合是连续的,但是您可以通过简单地调用集合上的
par
来实现并行执行

让我们举一个例子:

 (1 to 10).map { i => println(s"accessing sequentially $i") }
这将按预期提供以下顺序输出:

accessing sequentially 1
accessing sequentially 2
accessing sequentially 3
accessing sequentially 4
accessing sequentially 5
accessing sequentially 6
accessing sequentially 7
accessing sequentially 8
accessing sequentially 9
accessing sequentially 10
然而,我们可以通过使用
par
方法来实现并行执行

 (1 to 10).par.map { i => println(s"accessing parallel $i") }
这将提供以下输出:

accessing parallel 1
accessing parallel 2
accessing parallel 3
accessing parallel 4
accessing parallel 5
accessing parallel 8
accessing parallel 9
accessing parallel 10
accessing parallel 6
accessing parallel 7
我认为您看到混合输出语句的原因可能是,您的程序包含一些其他线程

另一种可能性是,您的集合是并行类型的

可以安全地删除您看到的偏执,而无需更改程序的输出。

对Scala集合调用的操作(如map)是按顺序执行还是并行执行,取决于集合的类型

默认情况下导入的集合是连续的,但是您可以通过简单地调用集合上的
par
来实现并行执行

让我们举一个例子:

 (1 to 10).map { i => println(s"accessing sequentially $i") }
这将按预期提供以下顺序输出:

accessing sequentially 1
accessing sequentially 2
accessing sequentially 3
accessing sequentially 4
accessing sequentially 5
accessing sequentially 6
accessing sequentially 7
accessing sequentially 8
accessing sequentially 9
accessing sequentially 10
然而,我们可以通过使用
par
方法来实现并行执行

 (1 to 10).par.map { i => println(s"accessing parallel $i") }
这将提供以下输出:

accessing parallel 1
accessing parallel 2
accessing parallel 3
accessing parallel 4
accessing parallel 5
accessing parallel 8
accessing parallel 9
accessing parallel 10
accessing parallel 6
accessing parallel 7
我认为您看到混合输出语句的原因可能是,您的程序包含一些其他线程

另一种可能性是,您的集合是并行类型的

您看到的偏执可以安全地删除,而无需更改程序的输出

括号可以在scala中启动新线程吗

没有

如何理解
(complete.map{})
的功能

与不带括号的
complete.map{…}
完全相同。括号是完全多余的。也许编写该代码的人认为需要在
map
之后调用
getOrElse
,但事实并非如此
complete.map{…}.getOrElse(byDate)
仍然是有效的语法,并且完全等效

因为,上述代码的输出被其他输出(在上述程序之后由一些代码打印出来)分隔开

如果看不到代码的其余部分(或者至少是
byDate
的类型),就无法确定为什么会发生这种情况,但一个似是而非的理论是,
byDate
是一个流,它的元素在您迭代时被评估。因此,如果
byDate
的定义包含print语句,那么这些语句将在您迭代
byDate
时执行

另一种理论是,您只是在其他地方启动多个线程

括号可以在scala中启动新线程吗

没有

如何理解
(complete.map{})
的功能

与不带括号的
complete.map{…}
完全相同。括号是完全多余的。也许编写该代码的人认为需要在
map
之后调用
getOrElse
,但事实并非如此
complete.map{…}.getOrElse(byDate)
仍然是有效的语法,并且完全等效

因为,上述代码的输出被其他输出(在上述程序之后由一些代码打印出来)分隔开

如果看不到代码的其余部分(或者至少是
byDate
的类型),就无法确定为什么会发生这种情况,但一个似是而非的理论是,
byDate
是一个流,它的元素在您迭代时被评估。因此,如果
byDate
的定义包含print语句,那么这些语句将在您迭代
byDate
时执行


另一种理论是,您只是在其他地方启动多个线程。

我更新了代码。仍然不知道多个线程是从哪里开始的。@BAE为什么你认为有多个线程?输出可以用单个线程上的延迟计算来解释。@TIm,是的,我已经知道了。我已经更新了我的帖子。原因是我更新了我的代码。仍然不知道多个线程是从哪里开始的。@BAE为什么你认为有多个线程?输出可以用单个线程上的延迟计算来解释。@TIm,是的,我已经知道了。我已经更新了我的帖子。原因是评估太慢