1. ホーム
  2. scala

[解決済み] ストリームとビューとイテレータ

2022-05-29 09:41:28

質問

scalaのStreams, View (SeqView), Iteratorの違いは何ですか?これは私の理解です。

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

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

どのように解決するのですか?

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

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

An Iterator は一度しか使えません。 トラバーサルポインタ であり,それ自体がコレクションではないからです.Scalaで特別なのは、以下のような変換を適用できることです。 mapfilter を取得し、単に新しい Iterator を取得し、次の要素を要求したときだけこれらの変換を適用します。

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

ビューはデータベースのビューと同じように見ることができます。それは、コレクションに適用して "仮想" コレクションを生成する、一連の変換です。あなたが言ったように、すべての変換は、そこから要素をフェッチする必要があるたびに再適用されます。

両方とも Iterator もビューも優れたメモリ特性を持っています。 Stream は良いものですが、Scalaでは、その主な利点は無限列(特に再帰的に定義された列)を書くことです。1つの を全て保持することを避けることができます. Stream への参照を保持しないようにすることで、すべての をメモリ内に保持することを避けることができます。 head への参照を保持しないようにすることです (例えば def の代わりに val を定義するために Stream ).

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