Ответ 1
Ваш код не копирует элементы последовательности, а sequenceOf(seq1, seq2).flatten()
выполняет то, что вам нужно: он генерирует последовательность, которая берет элементы сначала из seq1
, а затем, когда seq1
заканчивается, из seq2
.
Кроме того, оператор +
реализуется именно таким образом, поэтому вы можете просто использовать его:
(seq1 + seq2).forEach { ... }
Источник оператора как ожидалось:
public operator fun <T> Sequence<T>.plus(elements: Sequence<T>): Sequence<T> {
return sequenceOf(this, elements).flatten()
}
Вы можете взглянуть на реализацию .flatten()
в stdlib, которая использует FlatteningSequence
, который фактически переключает итераторы исходных последовательностей. Реализация может изменяться с течением времени, но Sequence
должна быть максимально ленивой, поэтому вы можете ожидать, что она будет вести себя аналогичным образом.
Пример:
val a = generateSequence(0) { it + 1 }
val b = sequenceOf(1, 2, 3)
(a + b).take(3).forEach { println(it) }
Здесь копирование первой последовательности никогда не будет успешным, так как оно бесконечно, а итерация по (a + b)
берет элементы один за другим из a
.
Обратите внимание, однако, что .flatten()
реализуется по-другому для Iterable
, а делает скопируйте элементы. Подробнее о различиях между Iterable
и Sequence
здесь.