web-dev-qa-db-ja.com

ストリームvsビューvsイテレーター

ScalaのStreams、Views(SeqView)、Iteratorの違いは何ですか?これは私の理解です:

  • それらはすべて遅延リストです。
  • ストリームは値をキャッシュします。
  • イテレータは一度しか使用できませんか?最初に戻って値を再度評価することはできませんか?
  • ビューの値はキャッシュされませんが、何度も評価できますか?

ヒープスペースを節約したい場合、イテレータ(リストを再度たどらない場合)またはビューを使用する必要がありますか?ありがとう。

131
JWC

まず、それらはすべて非厳密です。これは、機能に関連する特定の数学的意味を持ちますが、基本的に、事前にではなくオンデマンドで計算されることを意味します。

Streamは確かに遅延リストです。実際、Scalaでは、StreamListであり、そのtaillazy val。計算されると、値は計算されたままになり、再利用されます。または、あなたが言うように、値はキャッシュされます。

Iteratorは、コレクションへのトラバーサルポインターであり、それ自体のコレクションではないため、一度しか使用できません。 Scalaで特別なのは、mapfilterなどの変換を適用し、次の要素を要求したときにのみこれらの変換を適用する新しいIteratorを取得できるという事実です。

Scalaはリセット可能なイテレータを提供していましたが、一般的な方法でサポートするのは非常に難しく、バージョン2.8.0を作成しませんでした。

ビューは、データベースビューのように表示することを目的としています。これは、コレクションに適用して「仮想」コレクションを生成する一連の変換です。あなたが言ったように、すべての変換は、そこから要素を取得する必要があるたびに再適用されます。

Iteratorとビューの両方に優れたメモリ特性があります。 Streamはいいですが、Scalaでの主な利点は、無限シーケンス(特に再帰的に定義されたシーケンス)を書くことです。 1つcanただし、Streamへの参照を保持しないようにして(たとえば、headの代わりにdefを使用してvalを定義することにより)、Streamのすべてをメモリに保持しないようにします。

ビューにはペナルティがあるため、通常、変換を適用した後はforce、またはビューの合計サイズと比較して、フェッチされる要素が少ないと予想される場合はビューとして保持する必要があります。

178