По-перше, всі вони не суворі . Це має особливе математичне значення, пов'язане з функціями, але, в основному, означає, що вони обчислюються на вимогу, а не заздалегідь.
Streamце справді лінивий список. Насправді, у Scala, a Streamє Listчиєю tailє a lazy val. Після обчислення значення залишається обчисленим і повторно використовується. Або, як ви кажете, значення кешуються.
А Iteratorможе бути використаний лише один раз, тому що це вказівний перехід на колекцію, а не колекція сама по собі. Що робить його особливим у Scala, це те, що ви можете застосувати такі перетворення, як, mapі filterпросто отримати нове, Iteratorяке застосувати ці перетворення лише тоді, коли ви попросите наступного елемента.
Scala використовував для надання ітераторів, які можна було скинути, але це дуже важко підтримувати в загальному вигляді, і вони не склали версію 2.8.0.
Перегляди мають розглядатися приблизно як перегляд бази даних. Це серія перетворень, яка застосовується до колекції для створення "віртуальної" колекції. Як ви вже говорили, всі перетворення повторно застосовуються кожного разу, коли вам потрібно отримати елементи з нього.
І Iteratorвигляд, і вигляд мають відмінні характеристики пам'яті. StreamЦе приємно, але, в Scala, його головна перевага - це написання нескінченних послідовностей (зокрема, рекурсивно визначених послідовностей). Один може уникнути збереження всіх з Streamпам'яті, хоча, переконавшись , ви не тримаєте посилання на його head(наприклад, з використанням defзамість , valщоб визначити Stream).
Через штрафні санкції, спричинені переглядами, зазвичай forceслід застосовувати це після застосування перетворень або зберігати його як вигляд, якщо очікується, що коли-небудь буде витягнуто лише кілька елементів, порівняно із загальним розміром перегляду.