Kotlinの公式サイトで学ぶListとSetとMapの違いと使い方

## はじめに
 Kotlinの公式サイトを基にListとSetとMapの違いについて学んだことをまとめる。
本記事の対象者はKotlin初心者、プログラミングを初めたばかりの人向けの記事である。


## この記事の執筆のきっかけ
とある勉強会でKotlinの技術についてのLTがありました。
名前は知っていたけど使ったことがなかったので公式サイトでサンプルプログラミングを動かしてみようと見てみたら、かなり丁寧もドキュメントが書かれていてサンプルコードもたくさんあってびっくりしました。
ListとSetとMapについてまとめてあったページはKotlinを使用していない人にとっても有益だと思い、
KotlinでのListとSetとMapについて学んだことをまとめてみようと思いました。

公式サイトの今回教材にしたページはこちら。

https://kotlinlang.org/docs/kotlin-tour-collections.html


## ListとSetとMapとは
例えば、あなたがキャパ100人の学園祭の受付係だったとします。
キャパを超える人数は絶対に園内に入れるなとリーダから言われました。


100人に達しているかどうかを知りたいだけなら、紙のリストバンドを100枚用意して
入園希望者に渡していき、用意していたリストバンドが無くなったら、それ以降の入園希望者にお断りをすれば良いです。これが**Set**です。

<br>
しかし、ゾロ目の入園者にはプレゼントを渡すイベントを計画していたら、Setではうまくいきません。
入園した順番を管理する必要があるので、リストバンドに1から番号を記入していかないといけません。
この番号付きリストバンドが<strong>List</strong>です。
<br>
<br>
また、入園時間に応じてお菓子がもらえるイベントがあるとListでもうまくいきません。
入園者と入園時間を管理する必要があります。
そのためには、リストバンドを渡す時に、現在時刻を入園時間としてリストバンドに記入してから渡す必要があります。こういったように、何かの情報を紐づけて管理することが<strong>Map</strong>です。

<br><br>

この例えからなんとなく違いがイメージできたでしょうか。
ListとSetとMapを表にまとめると以下のようになります。
この表はKotlin公式サイトにも載っています。

| タイプ | 特徴 |
|:-:|:------------------|
| List  | アイテムの**順序付き**コレクション  |
| Set  | **順序のない**ユニークなアイテムのコレクション  |
| Map  | **キーと値のペアの集合**で、キーが一意であり、1つの値にのみマップされるもの  |


ではListとSetとMapについて簡単に説明したところで、
Kotlinの公式を見ながらListとSetとMapの使い方を確認します。

## List

ここからは公式ページに書いてある順に説明します。
公式ページは英語で書かれていますし、時々難しい表現があるので、
理解しにくい部分をサポートできるように簡素に書きます。


Listには`List`と`MutableList(ミュータブルリスト)`の2種類あります。
Listを作るときは`listOf`で、要素を設定し、
MutableListを作るときは、`mutableListOf`で設定をします。
こんな感じ。

```Kotlin:List
// Read only list
val readOnlyShapes = listOf("triangle", "square", "circle")
// Mutable list with explicit type declaration
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle") 
```

`List`はReadOnly、つまり一度listOfで作成した後は、要素の追加や変更、削除はできません。
`MutableList`は逆に要素の追加や変更、削除ができます。


List(またはMutableList)は上で書いた学園祭の例えでは順番を書いてあるリストバンドなので、
番号を指定したり、`first()`と書いて最初の要素を指定することもできます。
こんなかんじ。
```Kotlin:List
//MutableListでも同じだよ
val readOnlyShapes = listOf("triangle", "square", "circle")

println("The first item in the list is: ${readOnlyShapes[0]}")
//出力結果は下のとおり
// The first item in the list is: triangle


println("The first item in the list is: ${readOnlyShapes.first()}")
//出力結果は下のとおり
// The first item in the list is: triangle
```


また、`count()`を使って要素の数を数えることもできます。こんな感じ。
```Kotlin:List
val readOnlyShapes = listOf("triangle", "square", "circle")
println("This list has ${readOnlyShapes.count()} items")
//出力結果は下のとおり
// This list has 3 items
```

他には、`in`を使って要素があるかどうかを見つけることもできます。
出力結果は`true`か`false`です。
こんな感じ。
```Kotlin:List
val readOnlyShapes = listOf("triangle", "square", "circle")
println("circle" in readOnlyShapes)
//出力結果
// true
```
<br>

今度は、MutableListだけになりますが、要素を追加したり、削除したりする方法です。
追加するときは`add()`、削除するときは`remove()`を使います。こんな感じ。

```Kotlin:List
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
//  "pentagon" を追加するよ
shapes.add("pentagon") 
println(shapes)  
//出力結果は以下のとおり。
// [triangle, square, circle, pentagon]

// "pentagon" を削除するよ
shapes.remove("pentagon") 
println(shapes)  
//出力結果は以下のとおり。
// [triangle, square, circle]
```

Listはこんな感じで終わりです〜

## Set
Setは上の学園祭の例でいうと番号無しリストバンドです。
Setにも`Set`と`MutableSet`があります。Listと同じで
単なるSetは変更不可、MutableSetは変更できます。
Setの最初の設定はこんな感じ。それぞれ`setOf`か`mutableSetOf`を使います。

```Kotlin:Set
// Read-only set
val readOnlyFruit = setOf("apple", "banana", "cherry","cherry")
// Mutable set with explicit type declaration
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")

println(readOnlyFruit)
//出力結果は以下のとおり。
// [apple, banana, cherry]
```

setは同じ要素があったら一つと見なされます。
なので、上のコードをよく見るとSetOfやmutableSetOfで"cherry"が2つあるのですが、出力結果では"cherry"は一つです。
学園祭に入った人が一度学園から出て、また入ってきても2つ目のリストバンドは渡さないみないな感じです。

逆にListの場合は同じ要素でも追加できます。
学園祭に入った人が一度学園から出て、また入ってこようとしたら順番が変わってるから2つ目のリストバンドを渡しちゃおうって感じです。

setは順番を持っていないのでlistのように番号を指定することはできません。できるのは何個の要素があるかを知ることと要素がsetの中にあるかどうかを知ること、あとはlistでもあった追加と削除です。listと同じでそれぞれ`count()`、`in`、`add()`、`remove()`を使います。
countとinのコードはこんな感じです。
```Kotlin
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")

//要素の数が知りたいとき
println("This set has ${readOnlyFruit.count()} items")
//出力結果は以下のとおり。
// This set has 3 items

//指定の要素があるかどうか知りたいとき
println("banana" in readOnlyFruit)
//出力結果は以下のとおり。
// true

```

addとremoveはこんな感じです。
```Kotlin:Set
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
fruit.add("dragonfruit")    // Add "dragonfruit" to the set
println(fruit)              // [apple, banana, cherry, dragonfruit]

fruit.remove("dragonfruit") // Remove "dragonfruit" from the set
println(fruit)              // [apple, banana, cherry]
```

Setはこんな感じで終わりです。
ListもSetもどっちかが優位でどっちかが劣位というわけではなく、
ListがいいかSetがいいかは作るシステムの特性を見て決めないといけないですね。



## Map
最後はMapです。
Mapも変更不可の`Map`と変更可能な`MutableMap`があります。
Mapを設定するときは`mapOf`、MutableMapを設定するときは`mutableMapOf`を使います。
この辺はListやSetと似ています。
ただ、Mapは上で書いた学園祭の例えで言うと入園時間記載ありのリストバンドなので
入園時間と入園者名というように二つの情報を紐づけるために`to`を使います。
`to`の左側を`Key`、右側を`value`と呼びます。
コードはこんな感じ。

```Kotlin:Map
// Read-only map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
// Mutable map with explicit type declaration
val accountBalances: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)                    
```

`value`を取ってきたいときは`key`を指定します。
入園者名を知りたいとき、入園時間で検索するイメージです。
コードはこんな感じ。
```Kotlin:Map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println("The first value in the map is: ${readOnlyAccountBalances[1]}")
// 出力結果は以下の通り。
// The first value in the map is: 100
```

また、ListやMap同様に`count()`を使ってkeyとvalueのペア数を知ることもできます。
コードはこんな感じ。
```Kotlin:Map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println("This map has ${readOnlyAccountBalances.count()} key-value pairs")
// 出力結果は以下の通り。
// This map has 3 key-value pairs
```

MutableMapだけになりますが、追加と削除は`put()`、`remove()`でできます。
ListとSetのときは追加は`add()`でしたがMapのときは`put()`であることに注意が必要です。
コードはこんな感じ。
```Kotlin:Map
val accountBalances: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)
// keyが4でvalueが100という要素を追加する
accountBalances.put(4, 100)  
println(accountBalances)     
// 出力結果はこんな感じ。
// {1=100, 2=100, 3=100, 4=100}

//keyが4の要素を削除
accountBalances.remove(4)    
println(accountBalances)     
// 出力結果はこんな感じ。
// {1=100, 2=100, 3=100}

```

keyが存在しているか確認するときは`containsKey()`が必要です。
keyは一意になるものじゃないといけないのでcontainsKey()で確認をしましょう。
出力結果はすでにkeyが存在していたら`true`、存在していなかったら`false`となります。
学園祭の例えではkeyを一意にするために、入園時間の秒数まで記入しないといけないですね。
コードはこんな感じ。

```Kotlin:Map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(readOnlyAccountBalances.containsKey(2))
// 出力結果はこんな感じ。
// true
```

また、keyだけを知りたいときやvalueだけを知りたいときは`keys`や`values`を使います。
コードはこんな感じ。
```Kotlin:Map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(readOnlyAccountBalances.keys)
// 出力結果はこんな感じ。
// [1, 2, 3]
println(readOnlyAccountBalances.values)
// 出力結果はこんな感じ。
// [100, 100, 100]
```

最後に`containsKey()`ではない方法で指定のkeyがすでに存在するか調べる方法と、
指定のvalueがすでに存在する方法になります。
どちらも`in`を使って調べることができます。
出力結果はどちらも存在していたら`true`、存在していなかったら`false`となります。
コードはこんな感じ。
```Kotlin:Map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(2 in readOnlyAccountBalances.keys)
// 出力結果はこんな感じ。
// true
println(200 in readOnlyAccountBalances.values)
// 出力結果はこんな感じ。
// false
```

Mapはこれで終わりになります。

List、Set、Mapの説明やサンプルコードは全て公式サイトを引用させていただきました。
公式サイトは英語で書かれていますが、シンプルに説明されていて、とても有益です。



## 参考資料
Kotlinを学ぶためのサイトを紹介します。
私も全部は確認できていませんが、それぞれ読んでみたり使ってみました。


### Kotlin Programming Language
Kotlinの公式サイトです。まずはここを見ましょう。

https://kotlinlang.org/

### Kotlin Playground
Kotlinを環境構築なしでブラウザ上で動かすことができます。
公式サイトのコードをコピペしたり、一部を変えてコードの動きを確認しました。

https://play.kotlinlang.org/#eyJ2ZXJzaW9uIjoiMS45LjAiLCJwbGF0Zm9ybSI6ImphdmEiLCJhcmdzIjoiIiwibm9uZU1hcmtlcnMiOnRydWUsInRoZW1lIjoiaWRlYSIsImNvZGUiOiIvKipcbiAqIFlvdSBjYW4gZWRpdCwgcnVuLCBhbmQgc2hhcmUgdGhpcyBjb2RlLlxuICogcGxheS5rb3RsaW5sYW5nLm9yZ1xuICovXG5mdW4gbWFpbigpIHtcbiAgICBwcmludGxuKFwiSGVsbG8sIHdvcmxkISEhXCIpXG4gICAgdmFsIHNoYXBlczogTXV0YWJsZUxpc3Q8U3RyaW5nPiA9IG11dGFibGVMaXN0T2YoXCJ0cmlhbmdsZVwiLCBcInNxdWFyZVwiLCBcImNpcmNsZVwiKVxuLy8gIFwicGVudGFnb25cIiDjgpLov73liqDjgZnjgovjgohcbnNoYXBlcy5hZGQoXCJwZW50YWdvblwiKSBcbnByaW50bG4oc2hhcGVzKSAgXG59In0=

### Kotlin for Developers - App Development Guides
Android Appの公式サイトになります。いつかスマホアプリをリリースするのが夢です。

https://developer.android.com/kotlin?gclid=CjwKCAjw5MOlBhBTEiwAAJ8e1iGdkLX-HJvlSAdSyM_JXh2MhiwX8dOIEhswpwILbxpO_dAxwaiKDBoCF5gQAvD_BwE&gclsrc=aw.ds&hl=ja

## 最後に
Kotlin公式サイトには基本的な文法の学習以外にも、Ktorを使ってHTTP APIsを作るサンプルコードがあったり、Androidアプリの作成方法があったり、まだまだ勉強できることはたくさんあるので確認していきます〜。