scala.collection.mutable
のScalaのMutableList
クラスとListBuffer
クラスの違いは何ですか?いつどちらを使用しますか?
私のユースケースは、最初の要素を効率的に削除し、追加し、追加できる線形シーケンスを使用することです。これに最適な構造は何ですか?
それらがどのように機能するかについての少しの説明。
ListBuffer
は内部的にNil
と::
を使用して不変のList
を構築し、最初のおよび最後の要素を一定時間削除できるようにします。そうするために、リストの最初と最後の要素にポインターを保持し、実際には(そうでなければ不変の)::
クラスの先頭と末尾を変更できます(private[scala] var
の::
メンバーによって許可される素晴らしいトリック)。そのtoList
メソッドは、内部で維持されている構造を直接返すことができるため、通常の不変のList
も一定時間で返します。これは、不変のList
sのデフォルトのビルダーでもあります(したがって、一定時間の追加があることが合理的に期待できます)。 toList
を呼び出してから再度バッファに要素を追加すると、エクスポートされたリストを変更してはならないため、バッファ内の現在の要素数に対して線形時間がかかり、新しい構造が再作成されます。 。
MutableList
は内部的にLinkedList
と連携し、代わりに(::
のように)その要素と後続(::
のような)を知っている可変リンクリストの実装です。 MutableList
も最初と最後の要素へのポインタを保持しますが、結果のtoList
はList
から構築されるため、LinkedList
は線形時間で戻ります。したがって、List
がエクスポートされた後にバッファを再初期化する必要はありません。
要件を考えると、ListBuffer
とMutableList
は同等だと思います。ある時点で内部リストをエクスポートする場合は、オーバーヘッドが必要な場所を自問してください。リストをエクスポートするとき、そしてバッファを変更する場合はオーバーヘッドなし(次に、MutableList
を選択)、またはバッファを再度変更可能にし、エクスポート時に変更しない場合のみ(その後、ListBuffer
に移動します)。
私の推測では、2.8コレクションのオーバーホールでは、MutableList
はListBuffer
よりも古いBuilder
システム全体でした。実際、MutableList
は、主にcollection.mutable
パッケージ内から役立ちます。一定時間で返されるprivate[mutable] def toLinkedList
メソッドを備えているため、LinkedList
を維持するすべての構造の委任ビルダーとして効率的に使用できます。内部的に。
したがって、ListBuffer
やMutableList
のような「純粋に変更可能な」構造よりも将来的に注目され、最適化される可能性があるため、LinkedList
もお勧めします。
これにより、パフォーマンス特性の概要がわかります。 http://www.scala-lang.org/docu/files/collections-api/collections.html ;興味深いことに、MutableList
とListBuffer
はそこで違いはありません。 MutableList
のドキュメントには、Stack
とQueue
の基本クラスとして内部的に使用されていると書かれているので、ユーザーの観点からはListBuffer
の方が公式クラスでしょうか。
growableおよびshrinkableのリスト(なぜリストなのか)が必要であり、一定の追加と追加が必要です。さて、特性であるBuffer
には定数の追加と追加があり、他のほとんどの操作は線形です。 ListBuffer
を実装するクラスであるBuffer
は、最初の要素を一定時間削除していると思います。
ですから、私自身の推奨はListBuffer
です。
まず、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と比較して、機能的なデータ構造(不変性)です。
さて、見てみましょう
ListBuffer
List
に裏打ちされた可変バッファの実装。
MutableList
-LinkedListに基づく実装(代わりにLinkedListBuffer
という名前が付けられていればもっと自明だったでしょう)
ただし、List
からMutableList
を要求する場合は、既存の線形表現を、O(n)をとる再帰表現に変換する必要があります。 @ Jean-Philippe Pelletが指摘しているのはですが、Seq
からMutableList
を要求すると、複雑さはO(1)になります。
したがって、IMOの選択肢は、コードの詳細と好みに絞り込まれます。とはいえ、そこにはもっとたくさんのList
とListBuffer
があるのではないかと思います。
ListBufferはfinal /封印されていますが、MutableListを拡張できることに注意してください。アプリケーションによっては、拡張性が役立つ場合があります。