Tuż poniżej, kod ++
metody Iterator
„s:Iteratory wydajność konkatenacji
/** Concatenates this iterator with another.
*
* @param that the other iterator
* @return a new iterator that first yields the values produced by this
* iterator followed by the values produced by iterator `that`.
* @note Reuse: $consumesTwoAndProducesOneIterator
* @usecase def ++(that: => Iterator[A]): Iterator[A]
*/
def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator[B] {
// optimize a little bit to prevent n log n behavior.
private var cur : Iterator[B] = self
// since that is by-name, make sure it's only referenced once -
// if "val it = that" is inside the block, then hasNext on an empty
// iterator will continually reevaluate it. (ticket #3269)
lazy val it = that.toIterator
// the eq check is to avoid an infinite loop on "x ++ x"
def hasNext = cur.hasNext || ((cur eq self) && {
it.hasNext && {
cur = it
true
}
})
def next() = { hasNext; cur.next() }
}
W komentarzu, to mówi: // optimize a little bit to prevent n log n behavior.
.
Kiedy i w jaki sposób łączenie dwóch iteratorów prowadzi do n log n?
Jest to wspomniane w "Programowaniu w Scala 2nd ed.". Dziennik n wynika z dodatkowego pośrednictwa wprowadzonego przez decyzję o każdym kroku iteracji, jeśli następny element pochodzi z pierwszego lub drugiego iteratora. –
Jeśli sprawdzanie, który iterator jest pusty, będzie wykonywane cały czas, to łącząc konkatenacje z iteratorami konkatenacji, otrzymasz złą złożoność, która została naprawiona przez ponowne przypisanie nowej wartości do 'cur' – idonnie
Wielkie dzięki :) Jest to bardzo jasne . – Mik378