107
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[scala]なぜListではなくSeqを使うべきなのか

Last updated at Posted at 2015-02-26

Listは使わずにSeqにしなさいとよく言われるけど、何故そうなのかはいまいちよくわかってなかったので、調べました。基本的な内容です。

そもそもSeqとは

Seq(scala.collection.Seq)は、Iterableのうち順序を持つものを指します。
全てのcollectionはIterableであるので、順序がある(要素にindexでアクセスできる)コレクションは全てSeqです。(SeqでないコレクションにはMapやSetがあります)

Seqはscala.collection下にあるので、VectorだろうとMutableListだろうとSeqです。メソッドや関数の引数の型には、特別な理由がない限り、取りうる型の範囲を狭めてしまうListなどよりSeqを指定したほうが良さそうです。

scala> Seq
res0: scala.collection.Seq.type = scala.collection.Seq$@5680a178

scala> List
res1: scala.collection.immutable.List.type = scala.collection.immutable.List$@2d6a9952

IndexedSeqとLinearSeq

Seqは2種類のサブトレイトに分かれます。

  • IndexedSeq : 要素へのランダムアクセスとlengthが速い
  • LinearSeq : head/tailが速い

と、それぞれ異なるパフォーマンス特性を保証しています。

(immutableの方では)IndexedSeqのデフォルト実装はVectorであり、LinearSeqのデフォルト実装はListです。また、単純にSeqを作ったときもListが作成されます。
scala的にはindexアクセスはあまりしないでしょうから、SeqのデフォルトがLinearSeqなのは合理的と言えます。ちなみに、mutable.Seqはmutable.IndexedSeqと同じArrayBufferを作成します。

scala> Seq(1)
res2: Seq[Int] = List(1)

scala> IndexedSeq(1,2)
res3: IndexedSeq[Int] = Vector(1, 2)

基本的には「Listが使いたい」ことはあまりなくて、「先頭からのアクセスが速い配列が使いたい」ことのほうが多いとおもうので、scalaで配列的なものが使いたいときは、その使い方に応じてLinearSeq(Seq)かIndexedSeqを使うようにすれば良さそうです。

まとめ

  • 引数の型にはListよりSeqを使ったほうがいい
  • コンストラクタもListよりSeqを使ったほうがいい
107
89
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
107
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?