Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
88
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@i524

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

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を使ったほうがいい
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
88
Help us understand the problem. What are the problem?