私は多くの例でSeqが時々使われているのを見たことがありますが、それ以外の時はListです。
前のものがScala型で、ListがJavaから来ていること以外に何か違いはありますか?
Javaの用語では、ScalaのSeq
はJavaのList
になり、ScalaのList
はJavaのLinkedList
になります。
Seq
はtrait
であることに注意してください。これはJavaのinterface
と同等ですが、今後注目されるディフェンダーメソッドと同等のものです。 ScalaのList
は、Nil
の具体的な実装であるList
および::
によって拡張される抽象クラスです。
つまり、JavaのList
がinterface
の場合、ScalaのList
は実装です。
それ以上に、ScalaのList
は不変です。これはLinkedList
の場合ではありません。実際、Javaには不変のコレクションに相当するものはありません(読み取り専用で新しいオブジェクトを変更できないことが保証されているだけですが、古いオブジェクト、つまり「読み取り専用」コレクションを変更することはできます)。
ScalaのList
はコンパイラとライブラリによって非常に最適化されており、関数型プログラミングにおける基本的なデータ型です。しかし、それには限界があり、並列プログラミングには不十分です。最近では、Vector
はList
よりも良い選択ですが、習慣を破るのは難しいです。
Seq
はシーケンスの一般化に適しているため、インターフェイスにプログラムする場合はそれを使用する必要があります。 collection.Seq
、collection.mutable.Seq
、およびcollection.immutable.Seq
の3つが実際にあることに注意してください。スコープにインポートされる「デフォルト」は後者です。
GenSeq
とParSeq
もあります。後者は可能な限り並列に実行されますが、前者はSeq
とParSeq
の両方の親であり、コードの並列処理が重要でない場合に適した一般化です。それらはどちらも比較的新しく導入されたものなので、人々はまだそれらをあまり使っていません。
Seq
はList
が実装するトレイトです。
あなたのコンテナをSeq
として定義するなら、あなたはSeq
traitを実装するどんなコンテナも使うことができます。
scala> def sumUp(s: Seq[Int]): Int = { s.sum }
sumUp: (s: Seq[Int])Int
scala> sumUp(List(1,2,3))
res41: Int = 6
scala> sumUp(Vector(1,2,3))
res42: Int = 6
scala> sumUp(Seq(1,2,3))
res44: Int = 6
ご了承ください
scala> val a = Seq(1,2,3)
a: Seq[Int] = List(1, 2, 3)
の略語です:
scala> val a: Seq[Int] = List(1,2,3)
a: Seq[Int] = List(1, 2, 3)
コンテナー・タイプが指定されていない場合、基礎となるデータ構造はデフォルトでList
になります。
@ daniel-c-sobralが言ったように、Listは特性Seqを拡張し、scala.collection.immutable.$colon$colon
(または略して::
)によって実装される抽象クラスですが、技術的なことは別として、使用するリストとseqsのほとんどはSeq(1, 2, 3)
またはList(1, 2, 3)
の形式で初期化され、両方ともscala.collection.immutable.$colon$colon
を返すため、次のように記述できます。
var x: scala.collection.immutable.$colon$colon[Int] = null
x = Seq(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
x = List(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
その結果、重要なことは公開するメソッドだけであると主張します。たとえば、リストの::
を使用すると、SeqとIの+:
で冗長になることがありますデフォルトでは、Seqに個人的にこだわります。