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