ScalaでのSeqとListの違い


299

多くの例で、Seqが使用されていることもあれば、リストが使用されていることもありました...

前者がScala型であることとJavaからのリストである点以外に違いはありますか?

回答:


408

Javaの用語では、ScalaのSeqJavaのだろうList、とScalaのはList、JavaのだろうLinkedList

SeqあるtraitJavaのと同じです、interfaceしかし、新進気鋭のDF法の同等と。Scala Listは、Nilとによって拡張される抽象クラス::であり、の具体的な実装です。List

つまり、Java Listがであるinterface場合、Scala Listは実装です。

さらに、Scala Listは不変ですLinkedList。これはの場合とは異なります。実際、Javaには不変のコレクションに相当するものはありません(読み取り専用のものは、新しいオブジェクトを変更できないことを保証するだけですが、古いオブジェクトを変更できるため、「読み取り専用」のものを変更できます)。

Scala Listはコンパイラとライブラリによって高度に最適化されており、関数型プログラミングの基本的なデータ型です。ただし、制限があり、並列プログラミングには不十分です。最近でVectorは、がより良い選択ですListが、習慣を破るのは難しいです。

Seqシーケンスの一般化に適しているため、インターフェイスにプログラミングする場合は、それを使用する必要があります。:そこにそれらの3が実際にあることに注意してくださいcollection.Seqcollection.mutable.Seqそしてcollection.immutable.Seq、それはスコープにインポート「デフォルト」である後者の一つです。

GenSeqともありParSeqます。前者は両方の親であるが、後者の方法は、並列可能な場合に実行するSeqParSeq、コードの並列性は問題ではない場合に適した一般化です。どちらも比較的新しく導入されたため、まだあまり使用されていません。


3
REは、「Javaは不変コレクションに相当するものを持っていない」が、Stringコレクションではありません、それはJavaプログラマに馴染みの不変クラスの一例です。
huynhjl

15
@huynhjlそれは要点の外です。私はJavaに存在するものとScalaに存在するものとの類似点を描いていましたが、Javaには可変/不変コレクションの概念はありません。
Daniel C. Sobral

2
Javaには実際には不変のコレクションと同等のものがあります。これは「よく宣伝されている」わけではありませんが、そこにあり、ジェネリックを多用するUnsupportedOperationExceptionと、このためにヒットする可能性があります。Javaで不変のリストを作成するには、Collections.unmodifiableList()を使用します。同様に、セット、マップなどの他のメソッドがあります。docs.oracle.com
javase/

27
@jbx真実ではありません。これらのメソッドを使用すると、それを変更するメソッドに例外をスローするオブジェクトを取得しますが、不変オブジェクトは取得しません。変更不可能なオブジェクトが作成された後に元のオブジェクトが変更された場合、変更不可能なオブジェクトはそれを反映します。つまり、変更不可能、はい、不変、いいえ。
ダニエルC.ソブラル2013年

3
@jbx受信メソッドは、受信したコレクションへの参照を保持できず、変更されないことを前提としています。標準Javaライブラリには、それを保証する型はありません-それは不変性です。したがって、たとえば、その受信メソッドはスレッドの安全性を保証できません。そして、これは不変性によって可能になる永続的な特性にさえ触れません。それがなければ、「同等」とは言えません。
ダニエルC.ソブラル

81

A 配列は、要素の定義された順序を有する反復処理可能です。シーケンスは、apply()0からシーケンスの長さまでの範囲のインデックス作成方法を提供します。Seqには、Queue、Range、List、Stack、LinkedListなどの多くのサブクラスがあります。

A リストは不変リンクリストとして実装されている配列です。後入れ先出し(LIFO)アクセスパターンの場合に最適です。

以下は、Scala FAQの完全なコレクションクラス階層です。

ここに画像の説明を入力してください


2
配列(およびArrayBuffer)はどこですか?それは一種の反復可能ではありません
ピータークラウス

23

SeqList実装する特性です。

コンテナをとして定義するとSeqSeqトレイトを実装する任意のコンテナを使用できます。

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ます。


18

Scalaでは、リストはSeqを継承しますが、Productを実装します。リストの適切な定義は次のとおりです。

sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...

[注:Scalaの非常に強力なコレクションフレームワークに適合して利用するために実際の定義は少し複雑です。]


0

@ daniel-c-sobralが言ったように、Listは特性Seqを拡張し、scala.collection.immutable.$colon$colon(または::略して)実装された抽象クラスですが、専門性はさておき、使用するリストとseqのほとんどは、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から::冗長であることがわかったfrom Listを使用して+:、デフォルトで個人的にSeqに固執することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.