Во-первых, все они не строгие . Это имеет особое математическое значение, связанное с функциями, но, в основном, означает, что они вычисляются по требованию, а не заранее.
Stream
действительно ленивый список. На самом деле, в Scala, а Stream
есть List
чей tail
это lazy val
. После вычисления значение остается вычисленным и используется повторно. Или, как вы говорите, значения кэшируются.
Ан Iterator
можно использовать только один раз, потому что это указатель обхода в коллекцию, а не коллекция сама по себе. Что делает его особенным в Scala, так это тот факт, что вы можете применять преобразования, такие как map
и, filter
и просто получать новое, Iterator
которое будет применять эти преобразования только при запросе следующего элемента.
В Scala использовались итераторы, которые могли быть сброшены, но это очень сложно поддерживать в общем виде, и они не сделали версию 2.8.0.
Представления предназначены для просмотра во многом как представление базы данных. Это серия преобразований, которые применяются к коллекции для создания «виртуальной» коллекции. Как вы сказали, все преобразования повторно применяются каждый раз, когда вам нужно извлечь элементы из него.
Оба Iterator
и представления имеют отличные характеристики памяти. Stream
Это хорошо, но в Scala основным преимуществом является написание бесконечных последовательностей (особенно рекурсивно определенных последовательностей). Однако можно избежать хранения всей Stream
памяти, следя за тем, чтобы не хранить ссылку на нее head
(например, используя def
вместо val
определения Stream
).
Из-за штрафов, понесенных представлениями, обычно force
это следует делать после применения преобразований или сохранять его в качестве представления, если ожидается, что будет извлечено только несколько элементов, по сравнению с общим размером представления.