Чем отличается Iterator от Stream в Scala?
Кажется, что и Iterator и Stream ленивы и позволяют вам продолжать возвращать элементы к своему сердцу. Какая разница между этими двумя?
2 ответа
Поток запоминает, а Iterator - нет. Вы можете проходить один и тот же поток несколько раз и каждый раз получать один и тот же результат. Итератор, с другой стороны, может быть пройден только один раз.
Они оба являются конструкциями для доступа к текущему элементу, имея еще неизвестный список оставшихся элементов (ленивый хвост).
Iterator
это императивная конструкция, которую вы можете пройти только один раз.
Stream
является функциональной конструкцией Теоретически вы можете проходить его несколько раз (и, как уже упоминалось, он не будет пересчитывать уже вычисленные части), но на практике, потому что потоки либо бесконечны, либо очень велики (именно поэтому вы используете его в первую очередь), удерживая ссылка на полный поток не имеет большого смысла (вы легко сталкиваетесь с нехваткой памяти).
- Поэтому вы всегда должны определять потоки, используя
def
и никогда не помещайте его в локальные переменные, которые имеют долгосрочную область видимости. - Есть также тонкости при написании рекурсивных функций с использованием потоков,
- Там может быть некоторое неожиданное поведение в результате того, что Скала
Stream
не ленится в голове, вроде
Вообще разуму лучше избегать простого Stream
s. Альтернативы используют EphemeralStream
Scalaz, который автоматически забывает ненужные части, используя слабые ссылки, или используя Iteratees (см. также здесь) или что-то подобное.