web-dev-qa-db-ja.com

MutableListとListBufferの違い

scala.collection.mutableのScalaのMutableListクラスとListBufferクラスの違いは何ですか?いつどちらを使用しますか?

私のユースケースは、最初の要素を効率的に削除し、追加し、追加できる線形シーケンスを使用することです。これに最適な構造は何ですか?

33
Mike

それらがどのように機能するかについての少しの説明。

ListBufferは内部的にNil::を使用して不変のListを構築し、最初のおよび最後の要素を一定時間削除できるようにします。そうするために、リストの最初と最後の要素にポインターを保持し、実際には(そうでなければ不変の)::クラスの先頭と末尾を変更できます(private[scala] var::メンバーによって許可される素晴らしいトリック)。そのtoListメソッドは、内部で維持されている構造を直接返すことができるため、通常の不変のListも一定時間で返します。これは、不変のListsのデフォルトのビルダーでもあります(したがって、一定時間の追加があることが合理的に期待できます)。 toListを呼び出してから再度バッファに要素を追加すると、エクスポートされたリストを変更してはならないため、バッファ内の現在の要素数に対して線形時間がかかり、新しい構造が再作成されます。 。

MutableListは内部的にLinkedListと連携し、代わりに(::のように)その要素と後続(::のような)を知っている可変リンクリストの実装です。 MutableListも最初と最後の要素へのポインタを保持しますが、結果のtoListListから構築されるため、LinkedListは線形時間で戻ります。したがって、Listがエクスポートされた後にバッファを再初期化する必要はありません。

要件を考えると、ListBufferMutableListは同等だと思います。ある時点で内部リストをエクスポートする場合は、オーバーヘッドが必要な場所を自問してください。リストをエクスポートするとき、そしてバッファを変更する場合はオーバーヘッドなし(次に、MutableListを選択)、またはバッファを再度変更可能にし、エクスポート時に変更しない場合のみ(その後、ListBufferに移動します)。

私の推測では、2.8コレクションのオーバーホールでは、MutableListListBufferよりも古いBuilderシステム全体でした。実際、MutableListは、主にcollection.mutableパッケージ内から役立ちます。一定時間で返されるprivate[mutable] def toLinkedListメソッドを備えているため、LinkedListを維持するすべての構造の委任ビルダーとして効率的に使用できます。内部的に。

したがって、ListBufferMutableListのような「純粋に変更可能な」構造よりも将来的に注目され、最適化される可能性があるため、LinkedListもお勧めします。

35

これにより、パフォーマンス特性の概要がわかります。 http://www.scala-lang.org/docu/files/collections-api/collections.html ;興味深いことに、MutableListListBufferはそこで違いはありません。 MutableListのドキュメントには、StackQueueの基本クラスとして内部的に使用されていると書かれているので、ユーザーの観点からはListBufferの方が公式クラスでしょうか。

7
0__

growableおよびshrinkableのリスト(なぜリストなのか)が必要であり、一定の追加と追加が必要です。さて、特性であるBufferには定数の追加と追加があり、他のほとんどの操作は線形です。 ListBufferを実装するクラスであるBufferは、最初の要素を一定時間削除していると思います。

ですから、私自身の推奨はListBufferです。

5

まず、Scalaの関連するタイプのいくつかを見てみましょう

List-不変のコレクション。再帰的な実装、つまりつまり、リストのインスタンスには、headとtailの2つの主要な要素があり、tailは別のListを参照します。

List[T]
  head: T
  tail: List[T]  //recursive

LinkedList-一連のリンクされたノードとして定義された可変コレクション。各ノードには、値と次のノードへのポインターが含まれます。

Node[T]
  value: T
  next: Node[T]  //sequential

LinkedList[T]
  first: Node[T]

Listは、命令型言語でより標準的なLinkedListと比較して、機能的なデータ構造(不変性)です。

さて、見てみましょう

ListBufferListに裏打ちされた可変バッファの実装。

MutableList-LinkedListに基づく実装(代わりにLinkedListBufferという名前が付けられていればもっと自明だったでしょう)

どちらもほとんどの操作で同様の複雑さの限界を提供します。

ただし、ListからMutableListを要求する場合は、既存の線形表現を、O(n)をとる再帰表現に変換する必要があります。 @ Jean-Philippe Pelletが指摘しているのはですが、SeqからMutableListを要求すると、複雑さはO(1)になります。

したがって、IMOの選択肢は、コードの詳細と好みに絞り込まれます。とはいえ、そこにはもっとたくさんのListListBufferがあるのではないかと思います。

2
smartnut007

ListBufferはfinal /封印されていますが、MutableListを拡張できることに注意してください。アプリケーションによっては、拡張性が役立つ場合があります。

0
Herc