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