my codes:
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)
how to understand what (incomplete.map {})
does? From the output, I guess it starts another thread? Am I right? Because, the output of the above codes are separated by other outputs (which are printed out by some codes after the above piece of programs).
... other outputs generated by some codes after the above piece of codes ...
dd = 2018-05-11 vs i = 2018-05-12
dd = 2018-05-10 vs i = 2018-05-12
dd = 2018-05-13 vs i = 2018-05-12
dd = 2018-05-14 vs i = 2018-05-12
... other outputs generated by some codes after the above piece of codes ...
dd = 2018-05-10 vs i = 2018-05-12
dd = 2018-05-11 vs i = 2018-05-12
UPDATE
I already got one reason: filterKeys does evaluation lazily
, so, only after filtered
used, it starts evaluation.
can parentheses start a new thread in scala?
No.
how to understand what (incomplete.map {})
does?
The exact same thing as incomplete.map {...}
without the parentheses. The parentheses are entirely redundant. Perhaps whoever wrote that code thought the parentheses were needed to call getOrElse
after the map
, but that's not the case. incomplete.map {...}.getOrElse(byDate)
would still be valid syntax and completely equivalent.
Because, the output of the above codes are separated by other outputs (which are printed out by some codes after the above piece of programs).
It's impossible to say for sure why that happens without seeing the rest of your code (or at least the type of byDate
), but one plausible theory would be that byDate
is, say, a stream whose elements are evaluated as you iterate over it. So if the definition of byDate
contains print statements, those would be executed as you iterate over byDate
.
Another theory would be that you're simply starting multiple threads somewhere else.
Whether operations (like map) invoked on Scala's collections are executed sequentially or in parallel, depends on the type of your collection.
The collections that are imported by default are sequential, but you can achieve parallel execution by simply invoking par
on the collection.
Let us take an example:
(1 to 10).map { i => println(s"accessing sequentially $i") }
This gives as expected the following sequential output:
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
Whereas, we can achieve parallel execution by using the par
method
(1 to 10).par.map { i => println(s"accessing parallel $i") }
Which gives the following output:
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
I think the reason why you see mixed up output statements could be, that your program is containing some other threads?
Another possibility is, that your collection is of a parallel type.
The parantheses you see can safely be removed, without changing the output of the program.