scalaのListについて

scalaのリストについて調べてみたのでアウトプットのためにメモしておきます。

Listとは?

Listはscalaでも代表的なimmutableコレクション。
immutableコレクションなので、一度作成すると要素の追加・変更・削除はできません。もしそのような操作をしたい場合は、新しいListコレクションを作成します。
そのため元のコレクションはそのまま存在します。

定義の仕方は?

//NilはListの終わりを示す
scala> val nums = 1::2::Nil
nums: List[Int] = List(1, 2)

scala> val nums = List(1, 2)
nums: List[Int] = List(1, 2)

2つともやっていることは同じです。

要素の参照は?

//要素の参照
scala> nums(1)
res2: Int = 2

//その指定した要素がない場合
scala> nums(2)
java.lang.IndexOutOfBoundsException: 2
  at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:51)
  at scala.collection.immutable.List.apply(List.scala:83)
  ... 32 elided

こんなふうにパタンマッチで値をとりだすことも可能です。

scala> nums match {
     | case x::xs => println(x::xs)
     | case _ => println("error")
     | }
List(1, 2)

ちなみに下のようにxとxsを表示してみます。
xは先頭の数字で型はInt、xsは先頭を除く値を格納した型はList[Int]であることが分かります。

scala> val list = List(1, 2, 3, 4, 5)
list: List[Int] = List(1, 2, 3, 4, 5)

scala> list match {
     | case x::xs => println(x, xs)
     | case _ =>
     | }
(1,List(2, 3, 4, 5))

・Listの要素の取得するには

scala> val smartPhone = List("iPhone", "Xperia", "Galaxy", "Arrows", "Nexus")
smartPhone: List[String] = List(iPhone, Xperia, Galaxy, Arrows, Nexus)

//要素の最初を取得
scala> smartPhone.head
res1: String = iPhone

//最初の要素を除くリストを取得
scala> smartPhone.tail
res2: List[String] = List(Xperia, Galaxy, Arrows, Nexus)

//要素の最後を取得する
scala> smartPhone.last
res3: String = Nexus

//要素の順番を逆にする
scala> smartPhone.reverse
res4: List[String] = List(Nexus, Arrows, Galaxy, Xperia, iPhone)

・要素の追加は?

immutableなので直接追加はできません。
なので下のように要素を追加したListコレクションを作成することで要素の追加を行います。

//末尾に要素を追加したListを作成
scala> val moreSmartPhone = smartPhone :+ "Kindle Phone"
moreSmartPhone: List[String] = List(iPhone, Xperia, Galaxy, Arrows, Nexus, Kindle Phone)

//先頭に要素を追加したListを作成
scala> val moreAndMoreSmartPhone = "OnePlus one" :: smartPhone
moreAndMoreSmartPhone: List[String] = List(OnePlus one, iPhone, Xperia, Galaxy, Arrows, Nexus)

・要素の削除は?

scala> val lessSmartPhone = smartPhone.filter { _ != "Xperia" }
lessSmartPhone: List[String] = List(iPhone, Galaxy, Arrows, Nexus)

複数の要素の削除

scala> val target = List("Arrows", "Galaxy")
target: List[String] = List(Arrows, Galaxy)

scala> val smartPhone2 = smartPhone.filter { target.contains _ }
smartPhone2: List[String] = List(Galaxy, Arrows)

・Listの連結

scala> val ab = List("A", "B")
ab: List[String] = List(A, B)

scala> val cd = List("C", "D")
cd: List[String] = List(C, D)

//List同士の連結
scala> val abcd = ab ++ cd
abcd: List[String] = List(A, B, C, D)

scala> val ef = Array("E", "F")
ef: Array[String] = Array(E, F)

//ArrayとListの連結も可能
scala> val abef = ab ++ ef
abef: List[String] = List(A, B, E, F)

・Listと配列の使い分け

まずは両者の違いです。
List:要素を先頭から順にたどる必要があるため検索が遅い
Array:インデックス指定による特定の要素へのアクセスが高速

使い分け方はといいますと、
先頭の要素に対する操作が多い場合や要素を順に処理する場合はListを使います。
特定のインデックスへのアクセスが多い場合には配列を使うほうがいいでしょう。



本当に色んな使い方ができるので、なにかしたいことがある時にその都度確認してみます。
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List