Каковы различия между Streams, Views (SeqView) и Итераторами в scala? Это мое понимание:
Итак, если я хочу сохранить кучу пространства, следует ли использовать итераторы (если я не пройду список снова) или представления? Благодарю.
Во-первых, все они не являются строгими. Это имеет определенный математический смысл, связанный с функциями, но, в основном, означает, что они вычисляются по запросу, а не заранее.
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
его после применения преобразований или сохранить его как представление, если ожидается, что только несколько элементов будут получены, по сравнению с общим размером представления.
Iterator
также очень удобен для исследования бесконечности, и я обычно предпочитаю их потокам, где это возможно. Реальное преимущество в потоках заключается в том, что ранее полученные значения кэшируются, что является серьезным благом при попытке реализовать что-то вроде последовательности Фибоначчи, которая определяется в терминах предыдущих значений.