web-dev-qa-db-ja.com

scalaの配列とリストの違い

どのような場合にArray(Buffer)とList(Buffer)を使用する必要があります。私が知っている唯一の違いは、配列が不変であり、リストが共変であることです。しかし、パフォーマンスやその他の特性についてはどうでしょうか?

126
Jeriho

不変の構造

Scala Listは不変の再帰的データ構造であり、Scalaの基本的な構造であり、Array(実際にはmutable- immutable analog ArrayIndexedSeqです。

Javaバックグラウンド)から来ている場合、明らかな類似点はLinkedList over ArrayListを使用する場合です。前者は通常 traversed (およびそのサイズは前もって知られていない)一方で、後者は既知のサイズ(または最大サイズ)または fast randomのリストに使用されるaccess は重要です。

可変構造

ListBufferは、Listへの定数時間変換を提供します。これは、そのような後の変換が必要な場合にのみListBufferを使用する理由です。

scala Arrayは、Java配列、したがってArray[Int]は、はるかにパフォーマンスが高い場合があります(int[]List[Int](Scalaの新しい@specialized機能)。

ただし、ScalaでのArraysの使用は最小限に抑える必要があると思います。なぜなら、配列は、必要なプリミティブ型に実際に裏付けられているか、ラッパー型としてボックス化されている場合があります。

144
oxbow_lakes

既に投稿された回答に加えて、いくつかの詳細があります。

Array[A]は、文字通りJava配列、List[A]は、Nil(空のリスト)または(A, List[A])

パフォーマンスの違い

                          Array  List
Access the ith element    θ(1)   θ(i)
Delete the ith element    θ(n)   θ(i)
Insert an element at i    θ(n)   θ(i)
Reverse                   θ(n)   θ(n)
Concatenate (length m,n)  θ(n+m) θ(n)
Count the elements        θ(1)   θ(n)

メモリの違い

                          Array  List
Get the first i elements  θ(i)   θ(i)
Drop the first i elements θ(n-i) θ(1)
Insert an element at i    θ(n)   θ(i)
Reverse                   θ(n)   θ(n)
Concatenate (length m,n)  θ(n+m) θ(n)

したがって、高速なランダムアクセスが必要な場合、要素をカウントする必要がある場合、または何らかの理由で破壊的な更新が必要な場合を除き、ListArrayよりも優れています。

126
Apocalisp

配列は可変です。つまり、各インデックスの値を変更できますが、リスト(デフォルト)は不変です。つまり、変更を行うたびに新しいリストが作成されます。ほとんどの場合、不変のデータ型を扱うのがより「機能的な」スタイルであり、おそらくyieldforeachmatchなどの構造を持つListを使用する必要があります。前方へ。

パフォーマンス特性については、要素へのランダムアクセスでは配列が高速になりますが、新しい要素を追加(追加)するときはリストが高速になります。それらの繰り返しは同等です。

17
leonm