第8章：Scalaのコレクション(Seq, Set, Map)入門

まだまだ型だ！
今回は複数のインスタンスを束ねる __コレクション型__ 。
アプリケーションを作るには重要な型だ！
コレクションも奥が深いから、今回は入門と言う形にするよ！

# コレクション型
コレクションとは、複数のオブジェクトを一纏めにする箱のようなものだ。
Javaだと以下のインタフェースが有名だね。

- List
- Set
- Map

List、Mapは使われることが多いけど、Set人気はいまいちだ。
Setは、非常にパワフルな武器なんだけどね。。。
まぁそれは置いておいて。

Scalaで代表的な型は以下だ。

- Seq
- Set
- Map

Seqってなんでしょう？シーケンスです。順序を表す箱です。
Seqの実装クラスの1つにListがあったります。

ところでコレクションの全体像がどんな感じか気になりませんか？
そう思って調べたところ、絶句してしまった。

[ここ](http://www.scala-lang.org/api/current/#scala.collection.package)から[Content Hierarchy]をクリックして、クラス図的なモノを拡大してみましょう。
関係性がかなり複雑です。

今回は入門なので、1つずつを見ることはしないよ。

## イミュータブル・ミュータブル
先程挙げた型の説明の前に、コレクションのイミュータブル・ミュータブルについて。
なんとコレクションにもイミュータブル・ミュータブルの型が存在している。

JavaだとArrayListやHashSetなんかを使うことが多いから、
イミュータブルなんて気にすることがないと思う。

Scalaでは特に何も気にしなければ、イミュータブルなコレクションを使うことになるんだ。

例えば、以下のソース。

    scala> val numbers = Set(1, 2, 3)
    numbers: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

特に何もしていないので、イミュータブルなSetとなっている。

次に以下のソース。

    scala> import scala.collection.mutable.Set
    import scala.collection.mutable.Set
    
    scala> var numbers = Set(1, 2, 3)
    numbers: scala.collection.mutable.Set[Int] = Set(1, 2, 3)

これはミュータブルなSetだ。

ミュータブルなSetを使うには、明示が必要なんだ。
Map等でも同じだから、ミュータブルなコレクションを使うときには注意しよう！


ここからは代表的なSeq、Set、Mapを見てみよう。

# Seq
さっきも説明したけど、Seqとは順序を表す箱だよ。
要素の順序を意識する必要がある場合に、使う箱だ。
ソート順を保持するする場合とかに使えるよ。

ここではSeqの一種となっているListを見てみることにしよう。
JavaのListとはちょっと違うよ。

## List
早速Listを作ってみよう。

    scala> val numbers = List(1, 2, 3)
    numbers: List[Int] = List(1, 2, 3)
    
    scala> val numbers = 1 :: 2 :: 3 :: Nil
    numbers: List[Int] = List(1, 2, 3)
    
    scala> val numbers = 1 :: (2 :: (3 :: Nil))
    numbers: List[Int] = List(1, 2, 3)

3種類書いてみたけど、どれも`List(1, 2, 3)`を作っているんだ。
1番目はわかると思うけど、2番目・3番目の`::`、`Nil`がわからないって？

### Nil
空リストだよ。
Javaのライブラリ、Commons Collectionsの`ListUtils.EMPTY_LIST`みたいなモノだね。

###  ::(cons[コンス])
`::`はcons[コンス]って言うんだ。
`a :: b`は、先頭の要素が`a`でその後ろにリスト`b`が続いているリストを表す。

ということは、
`1 :: 2 :: 3 :: Nil`は、以下のように分解できる。

1. 先頭要素`3`で、後ろのリストがNilで構成されるリスト
1. 先頭要素`2`で、後ろのリストが1で生成したリストで構成されるリスト
1. 先頭要素`1`で、後ろのリストが2で生成したリストで構成されるリスト

となって、`List(1, 2, 3)`となるんだ。
これがわかれば、`1 :: (2 :: (3 :: Nil))`もわかるよね？

### Listの操作
基本操作は以下の3つになるんだ。

- head：先頭要素を返す
- tail：先頭要素を除く後ろのリスト
- isEmpty：リストが空なら`true`を返す

こんな感じで使えるんだ。

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

    scala> numbers.tail.head
    res5: Int = 2
    
    scala> numbers.tail.tail.head
    res6: Int = 3
    
    scala> numbers.tail.tail.isEmpty
    res7: Boolean = false
    
    scala> numbers.tail.isEmpty
    res8: Boolean = false
    
    scala> numbers.tail.tail.tail.isEmpty
    res9: Boolean = true

`::`の説明から追ってみてね！

# Set
集合を現す箱。
要素の重複を許さない箱だ。
なので、要素の重複をなくしたり、存在判定をするときに使えるね。

Setを生成して、使ってみよう！

    scala> val numbers = Set(1, 2, 3)
    numbers: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
    
    scala> numbers.contains(1)
    res15: Boolean = true
    
    scala> numbers.contains(4)
    res16: Boolean = false

ここでは、Set`numbers`に数字が入っているか確認しているぞ。

# Map
キーで値(要素)を特定することができる箱だ。
キーの重複はできないからね。

Mapを生成して、使ってみよう！

    scala> val colors = Map(1 -> "red", 2 -> "blue", 3 -> "black")
    colors: scala.collection.immutable.Map[Int,String] = Map(1 -> red, 2 -> blue, 3 -> black
    
    scala> colors(1)
    res13: String = red
    
    scala> colors(3)
    res14: String = black

ここでは、キーに該当する値を取得しているぞ。

# まとめ
今回はコレクション入門として代表的な
Seq, Set, Mapについて語ってみたけどどうかな？

次回以降に、それぞれの型についてもっと詳細に語る予定だよ。

今回も
__体で感じてくれたかな？__