2016-03-18 4 views
6

は、この質問にはいくつかの手がかりがあります:ScalaのSeqとIndexedSeq/LinearSeqの違いは何ですか? <a href="http://www.scala-lang.org/docu/files/collections-api/collections_5.html" rel="noreferrer">Scala Collection documentation</a>で

形質配列は2 subtraits LinearSeq、およびIndexedSeqを持っています。線形シーケンスは頭部と尾部の効率的な操作を行いますが、索引付けされたシーケンスは有効な適用、長さ、および(変更可能な場合)更新操作を行います。 IndexedSeqの代わりSeqを使用する際

しかし、これは私には対応していませんか? IndexedSeqまたはLinearSeqの実際の例が必要です。これらのコレクションはSeqより優れています。

答えて

12

Seqは超形質であるため、より一般的であり、すべての配列に共通の特徴(線形および索引付き)を有する。

あなたは、配列のコンパニオンオブジェクトSeq.applyの方法によって作成されたシーケンスの種類、我々は実装を見てすることができます迷っている場合。

あなたがSeq.applyを使用する場合は、あなたがあなただけの配列が必要であることを意味し、それはリニアですか

TLのインデックスを作成した場合、あなたのコードが気にしないことにしていることに注意してください; DRの答えがありますその後:

あなたは違いについて

を気にしないときこれがSeqのコンパニオンオブジェクトであるあなたは、特定の性能特性を持っている必要がある場合、あなたはより一般的なSeqを使用LinearSeqを使用するか

object Seq extends SeqFactory[Seq] { 
    implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] 

    def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A] 
} 

newBuilder[A]方法は、あなたが(トレイトGenericCompanion上で定義された)Seq.apply方法で確認することができるように、配列を構築するために使用されるものです:

def apply[A](elems: A*): CC[A] = { 
    if (elems.isEmpty) empty[A] 
    else { 
    val b = newBuilder[A] 
    b ++= elems 
    b.result() 
    } 
} 

さて質問です:何をしますかimmutable.Seq.newBuilder[A]ビルド?さんはimmutable.Seqコンパニオンオブジェクトに、この時間を見に行こう :

object Seq extends SeqFactory[Seq] { 
// stuff 
    def newBuilder[A]: Builder[A, Seq[A]] = new mutable.ListBuffer 
} 

それは可変ListBufferを構築します!何故ですか?これは、mutable.ListBufferBuilder[A, Seq[A]]であることもあります。これは、コレクションライブラリによって新しいコレクションを構築するために使用されるクラスです。

実際の出力コレクションは、この行(あなたが上記を参照できるよう)から来ている:だから

b.result() 

ListBuffer.result()の戻り値の型は何ですか? ListBufferで見てみましょう:

// Implementation of abstract method in Builder 
def result: List[A] = toList 

ここに行きます:それはリストです。

Seq(1,2,3)は、ボンネットの下にList[Int]を返しますが、ここで全体のポイントは、あなたは、配列を()を使用している場合は、より抽象的なことを暗示しているので、あなたが持っているコレクションの種類を知る必要がないということですインターフェイスはあなたのニーズに十分です

+0

追加するだけで、IndexedSeq.apply(ファクトリメソッド)を使用すると、Vectorが作成されます。 Seq.applyまたはLinearSeq.applyを使用すると、リストが表示されます。多くの場合Vectorが優先されるため、疑わしいときはIndexedSeq.applyを使用する必要があります。 – pumpump

3

Seqは単にIndexedSeqとLinearSeqのスーパー特性です。 SeqはSetとは対照的に順序付けされたリストであり、ユニークな&は通常は順序付けされておらず、Mapとは対照的に、キー値のペアです。
現在、IndexedSeqとLinearSeqがあります。
IndexedSeqサブクラスVector、Range、Stringはすべて高速インデックスベースのアクセスで、通常は高速アップデートです。これは、このような配列に適したデータ構造を内部的に(文字列のように)使用するか、ツリー(実際にはベクトルで使用される32個のファンアウトツリーthisを参照)、またはRange(これは3つの数字)を使用するためです。 。インデックスの計算が直接的である開始、終了、ステップ。
これに対して、LinearSeqはすべて低速インデックスベースのアクセスであり、更新が遅いです。通常、彼らはリンクされたリストの種類の構造を持っているからです。前置符号はすべてのキュー、スタック、リスト..のために速いですが、それは内部リンクリスト構造の端に行く必要があるので、悪名高く遅いです。それ自身の問題でトリックを使用するキューを除いて。トリックはhereと記載されています。
IndexedSeqは、高速インデックスベースのアクセスと更新を持つデータ構造であり、LinearSeqは高速プリペンドのデータ構造です。

関連する問題