Kotlin のコレクション使い方メモ

Kotlin のコレクションの使い方についてのメモ。

# Kotlin のコレクション
Kotlin には標準ライブラリが用意されており、その中にコレクションも存在する。

## 特徴
- Kotlin のコレクションは、「読み取り専用」と「書き込み可」のインターフェースが明確に分かれている。
- `listOf()`, `mapOf()` など、関数でインスタンスを生成する。
- Stream API に用意されているような `filter()` などのメソッドが、 `Iterable` などに定義されている。


## コレクションの種類
- [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)
- [Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)
- [Set](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/index.html)

## インターフェースの関係
![kotlin.collections.png](https://qiita-image-store.s3.amazonaws.com/0/28302/cfb98f23-45ee-f275-0f65-80dbf8e2d04a.png)

`kotlin.collections` パッケージの下にある各インターフェースがどのような関係になっているのか、クラス図で表現した。

基本は JDK のコレクションと同じ構成だが、 `MutableIterable` など書き込み可能かどうかを区別するためにインターフェースが追加されている。

`List` などの `Mutable` が付いていないインターフェースには、コレクションの状態を変更するメソッドが定義されていない。
これらのインターフェースはイミュータブルというわけではなく、あくまで読み取り専用でしかない。

### 読み取り専用とイミュータブルの違い
[Twitter で指摘](https://twitter.com/kmizu/status/739150557391118337)を受けたので修正します（完全に勘違いしてました、ありがとうございます）。

Kotlin の `List` や `Set` はあくまで「読み取り専用」であり、「イミュータブル」ではない。
例えば、以下のようなコードを書くと、簡単に `List` の中身を変更できてしまう。

```kotlin
fun main(args: Array<String>) {
    val mutableList = mutableListOf(1, 2, 3)
    val list: List<Int> = mutableList

    mutableList.add(9)

    println(mutableList)
    println(list)
}
```

```text:実行結果
[1, 2, 3, 9]
[1, 2, 3, 9]
```

`MutableList` は `List` を継承しているので、 `MutableList` を `List` の変数に代入することができる。
結果、 `List` の中身はどこか別の場所で書き換えられる可能性があることになる。

あくまで「読み取り専用」であって、「イミュータブル」ではないというのは、こういうことを意味している。


## Java のコレクションと Kotlin のコレクションのマッピング
Java のコレクション（`java.util.List` など）を Kotlin から使う場合、いくつかの型は自動的に Kotlin の型に変換される。

例えば、 `java.util.Iterator` 型は Kotlin 側のコードで使用する際は `kotlin.collection.Iterator` に変換される。
このため、 Java のコレクションを使用する場合も、 Kotlin に用意された便利なメソッド（`all()`, `filter()` など）を使用できるようになっている。

Java のどの型が、 Kotlin のどの型にマッピングされるかは、以下のページに書いてある。

[Mapped types | Calling Java code from Kotlin](https://kotlinlang.org/docs/reference/java-interop.html#mapped-types)


#コレクションの生成
Kotlin でコレクションを生成するには、専用のファクトリ関数を使用する。

## 読み取り専用のコレクションを生成する
```kotlin
val list = listOf(1, 2, 3)
val map = mapOf("foo" to "FOO", "bar" to "BAR")
val set = setOf(9, 8, 7)
```

- `listOf()`, `mapOf()`, `setOf()` 関数で、それぞれ読み取り専用のコレクションを生成できる。

### null を除いた List を生成する
```kotlin
fun main(args: Array<String>) {
    val list = listOf(null, 1, 2, 3, null)
    val notNullList = listOfNotNull(null, 1, 2, 3, null)

    println(list)
    println(notNullList)
}
```

```text:実行結果
[null, 1, 2, 3, null]
[1, 2, 3]
```

- `listOfNotNull()` メソッドを使うと、 `null` を取り除いたコレクションが生成される。

## 書き込み可能なコレクションを生成する
```kotlin
val list = mutableListOf(1, 2, 3)
val map = mutableMapOf("foo" to "FOO", "bar" to "BAR")
val set = mutableSetOf(9, 8, 7)
```

- `mutableListOf()`, `mutableMapOf()`, `mutableSetOf()` 関数で、それぞれ書き込み可能なコレクションを生成できる。

## Java 標準のコレクションを生成する
```kotlin
fun main(args: Array<String>) {
    printClass("arrayListOf", arrayListOf<Int>())

    printClass("hashSetOf", hashSetOf<Int>())
    printClass("linkedSetOf", linkedSetOf<Int>())
    printClass("sortedSetOf", sortedSetOf<Int>())
    
    printClass("hashMapOf", hashMapOf<Int, Int>())
    printClass("linkedMapOf", linkedMapOf<Int, Int>())
    printClass("sortedMapOf", sortedMapOf<Int, Int>())
}

fun printClass(functionName: String, collection: Any) {
    println("$functionName = ${collection.javaClass}")
}
```

```text:実行結果
arrayListOf = class java.util.ArrayList

hashSetOf = class java.util.HashSet
linkedSetOf = class java.util.LinkedHashSet
sortedSetOf = class java.util.TreeSet

hashMapOf = class java.util.HashMap
linkedMapOf = class java.util.LinkedHashMap
sortedMapOf = class java.util.TreeMap
```

- `arrayListOf()` など、 Java 標準のコレクションを生成できる関数が用意されている。


# プロパティ
## indices
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3)

    val indices: IntRange = list.indices
    println(indices)

    for (i in list.indices) {
        println(list[i])
    }
}
```

```text:実行結果
0..2
1
2
3
```

- `Array` または `Collection` に定義されているプロパティ。
- コレクションのインデックス範囲を表す `IntRange` オブジェクトが格納されている。
- `indices` は `index` の複数形。

## lastIndex
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3)

    println(list.lastIndex)
}
```

```text:実行結果
2
```

- `Array` または `List` に定義されているプロパティ。
- コレクションの最後のインデックスを取得できる。


# 特定のルールで命名されているメソッド
コレクションのメソッドの中には、ある特定のルールで名前が付けられているメソッドが存在する。

## To：処理結果を書き込み可能なコレクションに追加するメソッド
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    val result = mutableListOf("<9>")
    iterable.mapTo(result) { "<$it>" }

    println(result)
}
```

```text:実行結果
[<9>, <1>, <2>, <3>, <4>, <5>]
```

- 末尾に `To` がついたメソッドには、書き込み可能なコレクションを渡すことができる。
- 処理結果は、引数で渡した書き込み可能なコレクションに追加される。

## Indexed：繰り返し処理にループインデックスも渡す
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    iterable.forEachIndexed { index, value -> println("[$index] = $value") }
}
```

```text:実行結果
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
```

- メソッド名に `Indexed` が含まれるメソッドは、ラムダ式にループインデックスが渡される。

# メソッド逆引き
Stream API のあれ、 Kotlin のコレクションだとどれ？

|                Java                |                         Kotlin Collections                         |
|------------------------------------|--------------------------------------------------------------------|
| `Stream.allMatch()`                | [Iterable.all()](#all), [Map.all()](#all-1)                        |
| `Stream.anyMatch()`                | [Iterable.any()](#any), [Map.any()](#any-1)                        |
| `Stream.count()`                   | [Iterable.count()](#count), [Map.count()](#count-1)                |
| `Stream.distinct()`                | [Iterable.distinct()](#distinct)                                   |
| `Stream.filter()`                  | [Iterable.filter()](#filter), [Map.filter()](#filter-filternot)    |
| `Stream.findFirst()`               | [Iterable.first()](#first), [Iterable.firstOrNull()](#firstornull) |
| `Stream.flatMap()`                 | [Iterable.flatMap()](#flatmap), [Map.flatMap()](#flatmap-1)        |
| `Stream.forEach()`                 | [Iterable.forEach()](#foreach), [Map.forEach()](#foreach-1)        |
| `Stream.limit()`                   | [Iterable.take()](#take)                                           |
| `Stream.map()`                     | [Iterable.map()](#map), [Map.map()](#map-mapnotnull)               |
| `Stream.max()`                     | [Iterable.max()](#max-min), [Map.maxBy()](#maxby-minby-1)          |
| `Stream.min()`                     | [Iterable.min()](#max-min), [Map.minBy()](#maxby-minby-1)          |
| `Stream.noneMatch()`               | [Iterable.none()](#none), [Map.none()](#none-1)                    |
| `Stream.peek()`                    | なし？                                                             |
| `Stream.reduce()`                  | [Iterable.reduce()](#reduce)                                       |
| `Stream.sorted()`                  | [Iterable.sorted()](#sorted-sorteddescending)                      |
| `Stream.skip()`                    | なし？                                                             |
| `Stream.collect(toList())`         | [Iterable.toList()](#tolist), [Map.toList()](#tolist-1)            |
| `Stream.collect(toMap())`          | [Iterable.toMap()](#tomap)                                         |
| `Stream.collect(toSet())`          | [Iterable.toSet()](#toset)                                         |
| `Stream.collect(joining())`        | [Iterable.joinToString()](#jointostring)                           |
| `Stream.collect(partitioningBy())` | [Iterable.partition()](#partition)                                 |
| `Stream.collect(groupingBy())`     | [Iterable.groupBy()](#groupby)                                     |
| `Stream.collect(reducing())`       | [Iterable.fold()](#fold)                                           |
| `IntStream.sum()`                  | [Iterable.sum()](#sum)                                             |
| `IntStream.average()`              | [Iterable.average()](#average)                                     |


# Iterable 以下のメソッド
## Iterable のメソッド
### all()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.all { it < 4 })
    println(iterable.all { it < 3 })
}
```

```text:実行結果
true
false
```

- 全ての要素がラムダ式で指定した条件に一致する場合に `true` を返す。

### any()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.any { it < 4 })
    println(iterable.any { it < 0 })
}
```

```text:実行結果
true
false
```

- いずれかの要素がラムダ式で指定した条件に一致する場合に `true` を返す。

### associate()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    val map = iterable.associate { it to it*10 }

    println(map)
}
```

```text:実行結果
{1=10, 2=20, 3=30}
```

- 各要素ごとに `Pair` を返すことで、 `Map` に変換した結果を取得できる。

### associateBy()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    val map = iterable.associateBy { it*10 }

    println(map)
}
```

```text:実行結果
{10=1, 20=2, 30=3}
```

- 各要素に対してラムダ式が実行され、`キー:バリュー` が `ラムダ式が返した値:各要素のもとの値` となる `Map` が返される。

### average()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    val average = iterable.average()

    println(average)
}
```

```text:実行結果
2.0
```

- `Iterable` の各要素の平均値を取得する。
- このメソッドは、 `Iterable` の型引数が `Int` や `Float` など数値計算が可能な型の場合にのみ使用できる。
- `Iterable<String>` で使用しようとすると、コンパイルエラーになる。

### contains()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.contains(2))
    println(iterable.contains(4))
}
```

```text:実行結果
true
false
```

- 指定した要素が `Iterable` 内に存在するか確認する。

### count()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.count())
    println(iterable.count {it % 2 == 1})
}
```

```text:実行結果
3
2
```

- 要素数を取得できる。
- `boolean` を返すラムダ式を引数に渡すことで、条件に一致した要素の数だけをカウントできる。

### distinct()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 1, 2, 2, 3, 1, 3)

    println(iterable.distinct())
}
```

```text:実行結果
[1, 2, 3]
```

- 重複する要素を削除した結果を返す。

### distinctBy()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("foo", "bar", "fizz", "buzz", "hoge")

    println(iterable.distinctBy { it.length })
}
```

```text:実行結果
[foo, fizz]
```

- 重複を判断すための条件を、ラムダ式で指定する。
- ラムダ式が返した値が等しい要素は重複と判断される。

### drop()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.drop(2))
}
```

```text:実行結果
[3, 4, 5]
```

- 引数で指定した数だけ先頭から要素を削除して、残った要素をコレクションで返す。

### dropWhile()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.dropWhile { it != 4 })
}
```

```text:実行結果
[4, 5]
```

- ラムダ式が `true` を返すまでの要素を削除して、残った要素をコレクションで返す。

### elementAt()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.elementAt(2))
}
```

```text:実行結果
3
```

- 指定したインデックスの要素を取得する。
- インデックスが範囲外だった場合は `IndexOutOfBoundsException` がスローされる。

### elementAtOrElse()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.elementAtOrElse(0, { it * 10 }))
    println(iterable.elementAtOrElse(5, { it * 10 }))
}
```

```text:実行結果
1
50
```

- 指定したインデックスが範囲外だった場合に返す値を、第二引数のラムダ式で指定する。

### elementAtOrNull()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.elementAtOrNull(0))
    println(iterable.elementAtOrNull(5))
}
```

```text:実行結果
1
null
```

- 指定したインデックスが範囲外だった場合に `null` を返す。

### filter()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.filter { it % 2 != 0 })
}
```

```text:実行結果
[1, 3]
```

- ラムダ式で指定した条件に一致する要素だけを抽出してコレクションで返す。

### filterIsInstance()
```kotlin
fun main(args: Array<String>) {
    val iterable: Iterable<*> = listOf(1, "foo", 2.4, false)

    println(iterable.filterIsInstance<Number>())
    println(iterable.filterIsInstance(String::class.java))
}
```

```text:実行結果
[1, 2.4]
```

- 型パラメータで指定した型と互換のあるインスタンスだけを抽出してコレクションで返す。
- 引数に `Class` オブジェクトを渡すことで型を指定することもできる。


### filterNot()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)
    
    println(iterable.filterNot { it % 2 == 0 })
}
```

```text:実行結果
[1, 3, 5]
```

- ラムダ式で指定した条件に一致しない要素だけを抽出してコレクションで返す。

### filterNotNull()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, null, 3, null, 5)

    println(iterable.filterNotNull())
}
```

```text:実行結果
[1, 3, 5]
```

- `null` 要素を取り除いたコレクションで返す。

### find()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.find { it % 2 == 0 })
    println(iterable.find { it % 6 == 0 })
}
```

```text:実行結果
2
null
```

- ラムダ式で指定した条件に一致した最初の要素を取得する。
- 条件に一致する要素が存在しない場合は `null` を返す。

### findLast()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.findLast { it % 2 == 0 })
    println(iterable.findLast { it % 6 == 0 })
}
```

```text:実行結果
4
null
```

- ラムダ式で指定した条件に一致した最後の要素を取得する。
- 条件に一致する要素が存在しない場合は `null` を返す。

### first()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.first())
    println(iterable.first { it % 2 == 0 })
    println(iterable.first { it % 6 == 0 })
}
```

```text:実行結果
1
2
Exception in thread "main" java.util.NoSuchElementException: No element matching predicate was found.
```

- 先頭の要素を取得する。
- ラムダ式で条件を絞り込める。
- 該当する要素が存在しない場合は例外がスローされる。

### firstOrNull()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.firstOrNull())
    println(iterable.firstOrNull { it % 2 == 0 })
    println(iterable.firstOrNull { it % 6 == 0 })
}
```

```text:実行結果
1
2
null
```

- 先頭の要素を取得する。
- ラムダ式で条件を絞り込める。
- 該当する要素が存在しない場合は null が返される。


### last()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.last())
    println(iterable.last { it % 2 == 0 })
    println(iterable.last { it % 6 == 0 })
}
```

```text:実行結果
5
4
Exception in thread "main" java.util.NoSuchElementException: Collection doesn't contain any element matching the predicate.
```

- 最後の要素を取得する。
- 引数のラムダ式で、取得する条件を指定できる。
- 対応する要素が存在しない場合は、例外がスローされる。

### lastOrNull()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.lastOrNull())
    println(iterable.lastOrNull { it % 2 == 0 })
    println(iterable.lastOrNull { it % 6 == 0 })
}
```

```text:実行結果
5
4
null
```

- 最後の要素を取得する。
- 引数のラムダ式で、取得する条件を指定できる。
- 対応する要素が存在しない場合は、 null が返される。


### flatMap()
```kotlin
fun main(args: Array<String>) {
    val iterable: Iterable<Iterable<Int>> = listOf(
        listOf(1, 2, 3),
        listOf(4, 5, 6),
        listOf(7, 8, 9)
    )

    println(iterable.flatMap { it })
}
```

```text:実行結果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

- ラムダ式が返した `Iterable` を連結して返す。

### flatten()
```kotlin
fun main(args: Array<String>) {
    val iterable: Iterable<Iterable<Int>> = listOf(
        listOf(1, 2, 3),
        listOf(4, 5, 6),
        listOf(7, 8, 9)
    )

    println(iterable.flatten())
}
```

```text:実行結果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

- 入れ子の `Iterable` を、単一の `Iterable` に詰め替え直す（フラットにする）。

### fold()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("a", "b", "c")

    println(iterable.fold("Z", { buf, value -> buf + value }))
}
```

```text:実行結果
Zabc
```

- 第一引数で初期値を指定する。
- ラムダ式が各要素ごとにコールされる。
    - 第一引数には、初期値で指定した値が最初に渡され、以後は前回ラムダ式が返した値が渡される。
    - 第二引数には、 `Iterable` の各要素が渡される。

### forEach()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    iterable.forEach { println(it) }
}
```

```text:実行結果
1
2
3
```

- 各要素を処理する。

### groupBy()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5, 6, 7)

    val result1: Map<String, List<Int>> =
        iterable.groupBy { if (it % 2 == 0) "偶数" else "奇数" }

    println(result1)


    val result2: Map<String, List<String>> =
        iterable.groupBy(
            { if (it % 2 == 0) "偶数" else "奇数" },
            { "<$it>"}
        )

    println(result2)
}
```

```text:実行結果
{奇数=[1, 3, 5, 7], 偶数=[2, 4, 6]}
{奇数=[<1>, <3>, <5>, <7>], 偶数=[<2>, <4>, <6>]}
```

- ラムダ式が返した値ごとに各要素を分類して、 `Map` 詰めて返す。
- 第二引数にラムダ式を追加すれば、各要素を任意の値に変換できる。

### indexOfFirst()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.indexOfFirst { it % 2 == 0 })
}
```

```text:実行結果
1
```

- 指定したラムダ式の条件に一致する最初のインデックスを返す。

### indextOfLast()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.indexOfLast { it % 2 == 0 })
}
```

```text:実行結果
3
```

- 指定したラムダ式の条件に一致する最後のインデックスを返す。

### intersect()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)
    val other = listOf(2, 3, 5, 2)

    val result: Set<Int> = iterable.intersect(other)

    println(result)
}
```

```text:実行結果
[2, 3, 5]
```

- 引数で指定した `Iterable` と重複する要素だけを抽出して、 `Set` に詰めて返す。

### joinTo()
#### 基本
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)
    val buffer: Appendable = StringBuilder()

    iterable.joinTo(buffer)

    println(buffer)
}
```

```text:実行結果
1, 2, 3, 4, 5
```

- 各要素を連結した文字列を、指定した `Appendable` に設定する。
- デフォルトでは、各要素を半角カンマ区切りで連結した文字列が設定される。

#### 連結方法を調整する
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)
    val buffer: Appendable = StringBuilder()

    iterable.joinTo(
        buffer = buffer,
        separator = " - ",
        prefix = "{",
        postfix = "}",
        limit = 3,
        truncated = "(ry",
        transform = { "<$it>" }
    )

    println(buffer)
}
```

```text:実行結果
{<1> - <2> - <3> - (ry}
```

|引数|説明|デフォルト値|
|---|---|---|
|`separator`|区切り文字          |`, ` |
|`prefix`   |先頭に設定する文字列 |`""` |
|`postfix`  |末尾に設定する文字列 |`""` |
|`limit`    |連結する要素の最大値 |-1   |
|`truncated`|省略された要素の表記 |`...`|
|`transform`|各要素を任意の値に変換する処理|`null`|

### joinToString()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)
    
    println(iterable.joinToString())
}
```

```text:実行結果
1, 2, 3, 4, 5
```

- `joinTo()` メソッドの結果を `Appendable` に設定するのではなく、そのまま文字列として返却する。
- `separator` などの引数は、 `joinTo()` と同じように指定できる。

### map()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.map { it * 10 })
}
```

```text:実行結果
[10, 20, 30, 40, 50]
```

- 各要素をラムダ式が返した値で置き換えた新しいコレクションを返す。

### mapNotNull()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.mapNotNull { if (it % 2 == 0) it else null })
}
```

```text:実行結果
[2, 4]
```

- 各要素をラムダ式が返した値で置き換えた新しいコレクションを返す。
- ただし、ラムダ式が `null` を返した場合はスキップされる。

### max(), min()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.max())
    println(iterable.min())
}
```

```text:実行結果
5
1
```

- `max()` で最大の要素を取得する。
- `min()` で最小の要素を取得する。
- 要素は `Comparable` を実装している必要がある。

### maxBy(), minBy()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("zz", "yyy", "xxxx")

    println(iterable.maxBy { it.length })
    println(iterable.minBy { it.length })
}
```

```text:実行結果
xxxx
zz
```

- ラムダ式が返した値で大小を比較する。
- `maxBy()` で最大、 `minBy()` で最小を取得する。

### maxWith(), minWith()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.maxWith(Comparator { a, b -> b - a }))
    println(iterable.minWith(Comparator { a, b -> b - a }))
}
```

```text:実行結果
1
5
```

- 引数に `Comparator` を渡すことで、大小比較の方法を指定できる。
- `maxWith()` で最大、 `minWith()` で最小を取得する。

### minus()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 1, 2, 2, 3, 4, 5)
    val iterable2 = listOf(2, 4, 5);

    println(iterable1.minus(1))
    println(iterable1.minus(iterable2))
    println(iterable1 - iterable2)
}
```

```text:実行結果
[1, 2, 2, 3, 4, 5]
[1, 1, 3]
[1, 1, 3]
```

- 指定した要素を取り除いたコレクションを返す。
- 要素１つだけを引数に渡した場合は、該当する最初の要素だけが除去される。
- `Iterable` や `List`, `Sequence` を渡すこともできる。
- `-` 演算子で書き換えることもできる。


### plus()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 2, 3)
    val iterable2 = listOf(3, 5)

    println(iterable1.plus(6))
    println(iterable1.plus(iterable2))
    println(iterable1 + iterable2)
}
```

```text:実行結果
[1, 2, 3, 6]
[1, 2, 3, 3, 5]
[1, 2, 3, 3, 5]
```

- 指定した要素を追加したコレクションを返す。
- 他のコレクションを指定することもできる。
- `+` 演算子で書き換えることもできる。

### none()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 2, 3)
    val iterable2 = listOf<Int>();

    println(iterable1.none())
    println(iterable2.none())

    println(iterable1.none {it < 2})
    println(iterable1.none {it < 1})
}
```

```text:実行結果
false
true
false
true
```

- 要素を持たない場合に `true` を返す。
- ラムダ式で条件を絞り込める。

### partition()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    val pair: Pair<Iterable<Int>, Iterable<Int>> = iterable.partition { it % 2 == 0 }

    println(pair)
}
```

```text:実行結果
([2, 4], [1, 3, 5])
```

- ラムダ式で指定した条件で要素を二分して `Pair` で返す。
- 条件が `true` となった要素が `first` に、 `false` となった要素が `second` にセットされる。

### reduce()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("a", "b", "c")

    println(iterable.reduce {tmp, value ->
        println("tmp=$tmp, value=$value")
        tmp + ":" + value
    })
}
```

```text:実行結果
tmp=a, value=b
tmp=a:b, value=c
a:b:c
```

- ラムダ式による変換を積み重ねながら各要素を処理する。
- ラムダ式の第一引数には、初回は先頭要素が渡され、以後は前回ラムダ式が返した値が渡される。

### requireNoNulls()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("a", "b", null, "c")

    println(iterable.requireNoNulls())
}
```

```text:実行結果
Exception in thread "main" java.lang.IllegalArgumentException: null element found in [a, b, null, c].
    at kotlin.collections.CollectionsKt___CollectionsKt.requireNoNulls(_Collections.kt:1583)
```

- コレクション内に `null` が存在しないことを確認する。
- `null` が存在した場合は `IllegalArgumentException` がスローされる。

### reversed()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4)

    println(iterable.reversed())
}
```

```text:実行結果
[4, 3, 2, 1]
```

- 中身を逆順序にしたコレクションを返す。

### single()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(9)
    val iterable2 = listOf(1, 2, 3, 4)

    println(iterable1.single())
    println(iterable2.single {it == 3})
}
```

```text:実行結果
9
3
```

- コレクションが持つ唯一の要素を取得する。
- ラムダ式で条件を絞ることもできる。
- 以下のように、該当する要素が０または２件以上存在する場合は例外がスローされる。

```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4)

    println(iterable.single())
}
```

```text:実行結果
Exception in thread "main" java.lang.IllegalArgumentException: Collection has more than one element.
    at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:487)
```

### singleOrNull()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(9)
    val iterable2 = listOf(1, 2, 3, 4)


    println(iterable1.singleOrNull())
    
    println(iterable2.singleOrNull {it == 4})
    println(iterable2.singleOrNull())
}
```

```text:実行結果
9
4
null
```

- 基本は `single()` と同じだが、該当する要素が存在しない場合は `null` を返す点が異なる。

### sorted(), sortedDescending()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(3, 1, 2, 4)

    println(iterable.sorted())
    println(iterable.sortedDescending())
}
```

```text:実行結果
[1, 2, 3, 4]
[4, 3, 2, 1]
```

- 要素をソートしたコレクションを返す。
- `sorted()` は昇順ソート、 `sortedDescending()` は降順ソート。

### sortedBy(), sortedByDescending()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(3, 1, 2, 4)

    println(iterable.sortedBy { it * -1 })
    println(iterable.sortedByDescending { it * -1 })
}
```

```text:実行結果
[4, 3, 2, 1]
[1, 2, 3, 4]
```

- ソートの判定に使用する値を返すラムダ式を渡すことで、ソート方法を調整できる。
- `sortedBy()` は昇順ソート、 `sortedByDescending()` は降順ソート。

### sortedWith()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val iterable = listOf(3, 1, 2, 4)

    println(iterable.sortedWith(Comparator { left, right -> right - left }))
}
```

```text:実行結果
[4, 3, 2, 1]
```

- ソート方法を `Comparator` で実装して渡す。

### subtract()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 1, 2, 2, 3, 4, 5)
    val iterable2 = listOf(2, 3, 4)

    println(iterable1.subtract(iterable2))
}
```

```text:実行結果
[1, 5]
```

- 指定したコレクションに存在しない要素だけを抽出して `Set` で返す。
- 重複は除去される。

### sum()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.sum())
}
```

```text:実行結果
6
```

- コレクションの各要素の合計を返す。
- コレクションの要素は数値計算が可能な型である必要がある。

### sumBy()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.sumBy { it * 10 })
}
```

```text:実行結果
60
```

- ラムダ式が返した値で合計を計算する。

### sumByDouble()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    println(iterable.sumByDouble { it * 1.5 })
}
```

```text:実行結果
9.0
```

- ラムダ式が返す `Double` 値で合計を算出する。

### take()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.take(3))
}
```

```text:実行結果
[1, 2, 3]
```

- 先頭から指定した数だけ要素を取得して `List` で返す。

### takeWhile()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    println(iterable.takeWhile { it < 5 })
}
```

```text:実行結果
[1, 2, 3, 4]
```

- 先頭から、ラムダ式で指定した条件が満たされなくなるまで要素を取得して `List` で返す。

### toCollection()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    val result: MutableCollection<Int> = mutableListOf(9)

    iterable.toCollection(result)

    println(result)
}
```

```text:実行結果
[9, 1, 2, 3]
```

- 指定した `MutableCollection` に要素を追加する。

### toHashSet()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val iterable = listOf(1, 1, 2, 2, 2, 3, 3)

    val result: HashSet<Int> = iterable.toHashSet()

    println(result)
}
```

```text:実行結果
[1, 2, 3]
```

- `HashSet` に変換する。

### toList()
```kotlin
fun main(args: Array<String>) {
    val iterable = setOf(1, 2, 3)

    val list: List<Int> = iterable.toList()

    println(list)
}
```

```text:実行結果
[1, 2, 3]
```

- `List` に変換する。

### toMap()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("foo" to "FOO", "bar" to "BAR")

    val map: Map<String, String> = iterable.toMap()

    println(map)

    val result = mutableMapOf("fizz" to "FIZZ")

    iterable.toMap(result)

    println(result)
}
```

```text:実行結果
{foo=FOO, bar=BAR}
{fizz=FIZZ, foo=FOO, bar=BAR}
```

- `Iterable<Pair<K, V>>` を `Map<K, V>` に変換する。
- 引数に `MutableMap` を渡すと、その `Map` に追加される。

### toMutableList()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3)

    val result: MutableList<Int> = iterable.toMutableList()

    println(result)
}
```

```text:実行結果
[1, 2, 3]
```

- `MutableList` に変換する。


### toMutableSet()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 1, 2, 3, 3)

    val result: MutableSet<Int> = iterable.toMutableSet()

    println(result)
}
```

```text:実行結果
[1, 2, 3]
```

- `MutableSet` に変換する。

### toSet()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 1, 2, 3, 3)

    val result: Set<Int> = iterable.toSet()

    println(result)
}
```

```text:実行結果
[1, 2, 3]
```

- `Set` に変換する。

### toSortedSet()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val iterable = listOf(3, 1, 2, 3, 1, 4)

    val result: SortedSet<Int> = iterable.toSortedSet()

    println(result)
}
```

```text:実行結果
[1, 2, 3, 4]
```

- `SortedSet` に変換する。

### union()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 2, 3, 4)
    val iterable2 = listOf(2, 4, 5, 6)

    val result: Set<Int> = iterable1.union(iterable2)

    println(result)
}
```

```text:実行結果
[1, 2, 3, 4, 5, 6]
```

- ２つの `Iterable` の要素を合計して `Set` で返す。

### unzip()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf("one" to 1, "two" to 2, "three" to 3)

    val result: Pair<List<String>, List<Int>> = iterable.unzip()

    println(result)
}
```

```text:実行結果
([one, two, three], [1, 2, 3])
```

- `List<Pair<T, U>>` を `Pair<List<T>, List<U>>` に変換する。

### withIndex()
```kotlin
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4, 5)

    val result: Iterable<IndexedValue<Int>> = iterable.withIndex()

    result.forEach { println("index=${it.index}, value=${it.value}") }
}
```

```text:実行結果
index=0, value=1
index=1, value=2
index=2, value=3
index=3, value=4
index=4, value=5
```

- `Iterable<IndexedValue<T>>` に変換する。

### zip()
```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 2, 3)

    val iterable2 = listOf("one", "two", "three", "four")
    val result1: List<Pair<Int, String>> = iterable1.zip(iterable2)
    println(result1)

    val array = arrayOf(1.1, 2.2)
    val result2: List<Pair<Int, Double>> = iterable1.zip(array)
    println(result2)
}
```

```text:実行結果
[(1, one), (2, two), (3, three)]
[(1, 1.1), (2, 2.2)]
```

- ２つの `Iterable`（または `Array`） の各要素を１つの `Pair` にして、 `List` に詰めて返す。
- 要素数が合わない場合は、少ないほうに合わせられる。
- 以下のようにラムダ式で各要素を変換することもできる。

```kotlin
fun main(args: Array<String>) {
    val iterable1 = listOf(1, 2, 3)

    val iterable2 = listOf("one", "two", "three", "four")
    val result1: List<String> = iterable1.zip(iterable2, {a, b -> "$b($a)"})
    println(result1)

    val array = arrayOf(1.1, 2.2)
    val result2: List<Int> = iterable1.zip(array, {a, b -> (a + b*10).toInt()})
    println(result2)
}
```

```text:実行結果
[one(1), two(2), three(3)]
[12, 24]
```

## Collection のメソッド
### containsAll()
```kotlin
fun main(args: Array<String>) {
    val collection1 = listOf(1, 2, 3, 4)
    val collection2 = listOf(2, 3)
    val collection3 = listOf(4, 5)

    println(collection1.containsAll(collection2))
    println(collection1.containsAll(collection3))
}
```

```text:実行結果
true
false
```

- 指定したコレクションに含まれる全ての要素を持つかどうかを確認する。

### isEmpty(), isNotEmpty()
```kotlin
fun main(args: Array<String>) {
    val collection1 = listOf(1, 2, 3, 4)
    val collection2 = listOf<Int>()

    println(collection1.isEmpty())
    println(collection2.isEmpty())

    println(collection1.isNotEmpty())
    println(collection2.isNotEmpty())
}
```

```text:実行結果
false
true
true
false
```

- コレクションが空かどうか確認できる。

### orEmpty()
```kotlin
fun main(args: Array<String>) {
    val collection1 = listOf(1, 2, 3, 4)
    val collection2: Collection<Int>? = null

    println(collection1.orEmpty())
    println(collection2.orEmpty())
}
```

```text:実行結果
[1, 2, 3, 4]
[]
```

- コレクションの型が `null` 可で、かつ実際 `null` だった場合は空のコレクションを返す。
- そうでない場合は、自分自身をそのまま帰す。

### to***Array()
```kotlin
fun main(args: Array<String>) {
    val collection = listOf(1, 2, 3, 4)

    val array: IntArray = collection.toIntArray()

    array.forEach { println(it) }
}
```

```text:実行結果
1
2
3
4
```

- `***Array` に変換する。
- `Boolean`, `Byte`, `Char`, `Double`, `Float`, `Int`, `Long`, `Short` がある。

### toTypedArray()
```kotlin
fun main(args: Array<String>) {
    val collection = listOf(1, 2, 3, 4)

    val array: Array<Int> = collection.toTypedArray()

    array.forEach { println(it) }
}
```

```text:実行結果
1
2
3
4
```

- `Array<T>` に変換する。

## List のメソッド
### asReversed()
```kotlin
fun main(args: Array<String>) {
    val list = mutableListOf(1, 2, 3)

    println("[before] list = $list")

    val asReversed = list.asReversed()

    println("[after asReversed] list = $list")
    println("[after asReversed] asReversed = $asReversed")

    list += 9
    asReversed += 99

    println("[after modify] list = $list")
    println("[after modify] asReversed = $asReversed")
}
```

```text:実行結果
[before] list = [1, 2, 3]
[after asReversed] list = [1, 2, 3]
[after asReversed] asReversed = [3, 2, 1]
[after modify] list = [99, 1, 2, 3, 9]
[after modify] asReversed = [9, 3, 2, 1, 99]
```

- 順序を逆転させた `List` を返す。
- `reversed()` との違いは、 `MutableList` の場合は `MutableList` を返すという点。
    - `reversed()` の場合は `List` を返す。
- 返された `List` と元の `List` は関連しており、一方を変更すると他方にも変更が反映される。

### binarySearch()
#### 基本
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val list = listOf(1, 2, 2, 3, 3, 3)

    println(list.binarySearch(3))
    println(list.binarySearch(9))
    println(list.binarySearch(element = 3, fromIndex = 0, toIndex = 2))
    println(list.binarySearch(element = 3, comparator = Comparator { a, b -> a - b }))
}
```

```text:実行結果
4
-7
-3
4
```

- バイナリサーチで指定した要素を検索し、該当した場所のインデックスを返す。
    - 要素が見つからなかった場合は負数が返される。
- `List` はあらかじめソートされている必要がある。
    - ソートされていない場合はデタラメな値を返す。
- 第二引数（`fromIndex`）と第三引数（`toIndex`）で、検索の範囲を指定できる。
- `comparator` で、要素の比較方法を指定できる。

### binarySearchBy()
```kotlin
fun main(args: Array<String>) {
    val list = listOf("I", "he", "her", "you")

    println(list.binarySearchBy("Thank you", selector = { "Thank $it" }))
}
```

```text:実行結果
3
```

- 各要素を `selector` で変換して、その値に一致する項目を検索し、該当するインデックスを返す。
- `List` はソートされている必要がある。

### component*()
```kotlin
fun main(args: Array<String>) {
    val list = listOf("one", "two", "three", "four", "five")

    println(list.component1())
    println(list.component2())
    println(list.component3())
    println(list.component4())
    println(list.component5())
}
```

```text:実行結果
one
two
three
four
five
```

- １～５番目までの要素を取得する。
- 使いドコロは・・・不明。

### dropLast()
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3, 4, 5)

    println(list.dropLast(2))
}
```

```text:実行結果
[1, 2, 3]
```

- 指定した数だけ、要素を後ろから削除した結果を `List` で返す。

### dropLastWhile()
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3, 4, 5)

    println(list.dropLastWhile { it > 2 })
}
```

```text:実行結果
[1, 2]
```

- ラムダ式が `true` を返す間、末尾から要素を削除し、残った要素を `List` に詰めて返す。

### foldRight()
```kotlin
fun main(args: Array<String>) {
    val list = listOf("a", "b", "c")

    println(list.foldRight("Z", { value, buf -> buf + value }))
}
```

```text:実行結果
Zcba
```

- 末尾から順番に要素を処理し、結果を蓄積していく。
- ラムダ式の第二引数には、初回は第一引数で渡した初期値が渡され、二回目以降は前回ラムダ式が返した値が渡される。


- 第一引数で初期値を指定する。
- ラムダ式が各要素ごとにコールされる。
    - 第一引数には、初期値で指定した値が最初に渡され、以後は前回ラムダ式が返した値が渡される。
    - 第二引数には、 `Iterable` の各要素が末尾から順番に渡される。

### getOrElse()
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3)

    println(list.getOrElse(0, { 9 }))
    println(list.getOrElse(4, { 9 }))
}
```

```text:実行結果
1
9
```

- 指定したインデックスの要素を取得する。
- インデックスが範囲外の場合は、ラムダ式が返す値をデフォルト値として返す。

### getOrNull()
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3)

    println(list.getOrNull(0))
    println(list.getOrNull(4))
}
```

```text:実行結果
1
null
```

- 指定したインデックスの要素を取得する。
- インデックスが範囲外の場合は、 `null` を返す。

### reduceRight()
```kotlin
fun main(args: Array<String>) {
    val list = listOf("a", "b", "c")

    println(list.reduceRight { value, tmp ->
        println("value=$value, tmp=$tmp")
        tmp + ":" + value
    })
}
```

```text:実行結果
value=b, tmp=c
value=a, tmp=c:b
c:b:a
```

- ラムダ式による変換を積み重ねながら各要素を末尾から順番に処理する。
- ラムダ式の第一引数には、初回は末尾の要素が渡され、以後は前回ラムダ式が返した値が渡される。

### slice()
```kotlin
fun main(args: Array<String>) {
    val list = listOf("0:one", "1:two", "2:three", "3:four", "4:five")
    println(list.slice(2..4))

    val indices = listOf(1, 3, 4)
    println(list.slice(indices))
}
```

```text:実行結果
[2:three, 3:four, 4:five]
[1:two, 3:four, 4:five]
```

- インデックスの指定で要素を抜き取る。
- `IntRange` を使うと、範囲指定で要素を抜き取ることができる。
- `Iterable` を使うと、指定したインデックスの要素だけを抜き取ることができる。

### takeLast()
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3, 4, 5)

    println(list.takeLast(2))
}
```

```text:実行結果
[4, 5]
```

- 指定した数だけ末尾から要素を取得し、 `List` にして返す。

### takeLastWhile()
```kotlin
fun main(args: Array<String>) {
    val list = listOf(1, 2, 3, 4, 5)

    println(list.takeLastWhile { it > 2 })
}
```

```text:実行結果
[3, 4, 5]
```

- ラムダ式が `true` を返す間、末尾から順番に要素を取得し、 `List` に詰めて返す。

## MutableIterable のメソッド
### removeAll()
```kotlin
fun main(args: Array<String>) {
    val mutableIterable = mutableListOf(1, 2, 3, 1, 2, 3)

    mutableIterable.removeAll { it == 3 }

    println(mutableIterable)
}
```

```text:実行結果
[1, 2, 1, 2]
```

- ラムダ式で指定した条件に一致する要素を全て削除する。

### retainAll()
```kotlin
fun main(args: Array<String>) {
    val mutableIterable = mutableListOf(1, 2, 3, 1, 2, 3)

    mutableIterable.retainAll { it == 3 }

    println(mutableIterable)
}
```

```text:実行結果
[3, 3]
```

- ラムダ式で指定した条件に一致する要素だけを残し、残りを全て削除する。

## MutableCollection のメソッド
### addAll()
```kotlin
fun main(args: Array<String>) {
    val mutableCollection = mutableListOf(1, 2, 3)
    val iterable = listOf(7, 8, 9)

    mutableCollection.addAll(iterable)

    println(mutableCollection)
}
```

```text:実行結果
[1, 2, 3, 7, 8, 9]
```

- 指定したコレクションの要素を全て追加する。

### minusAssign()
```kotlin
fun main(args: Array<String>) {
    val mutableCollection = mutableListOf(1, 2, 3, 4, 5)
    val iterable = listOf(2, 4)

    mutableCollection.minusAssign(iterable)
    println(mutableCollection)

    mutableCollection -= 5
    println(mutableCollection)
}
```

```text:実行結果
[1, 3, 5]
[1, 3]
```

- コレクションまたは単独で指定した要素を削除する。
- `-=` で置き換えることができる。

### plusAssign()
```kotlin
fun main(args: Array<String>) {
    val mutableCollection = mutableListOf(1, 2, 3)
    val iterable = listOf(7, 8)

    mutableCollection.plusAssign(iterable)
    println(mutableCollection)

    mutableCollection += 9
    println(mutableCollection)
}
```

```text:実行結果
[1, 2, 3, 7, 8]
[1, 2, 3, 7, 8, 9]
```

- コレクションまたは単独で指定した要素を追加する。
- `+=` で置き換えることができる。


### remove()
```kotlin
fun main(args: Array<String>) {
    val mutableCollection = mutableListOf(1, 2, 3)

    mutableCollection.remove(2)

    println(mutableCollection)
}
```

```text:実行結果
[1, 3]
```

- 指定した要素を削除する。

## MutableList のメソッド
### reverse()
```kotlin
fun main(args: Array<String>) {
    val mutableList = mutableListOf(1, 2, 3)

    mutableList.reverse()

    println(mutableList)
}
```

```text:実行結果
[3, 2, 1]
```

- 順序を逆にする。

### sort(), sortDescending()
```kotlin
fun main(args: Array<String>) {
    val mutableList = mutableListOf(3, 1, 2)

    mutableList.sort()
    println(mutableList)

    mutableList.sortDescending()
    println(mutableList)
}
```

```text:実行結果
[1, 2, 3]
[3, 2, 1]
```

- 要素をソートする。
- `sort()` が昇順、 `sortDescending()` が降順。

### sortBy(), sortByDescending()
```kotlin
fun main(args: Array<String>) {
    val mutableList = mutableListOf("aaa", "bb", "c")

    mutableList.sortBy { it.length }
    println(mutableList)

    mutableList.sortByDescending { it.length }
    println(mutableList)
}
```

```text:実行結果
[c, bb, aaa]
[aaa, bb, c]
```

- ラムダ式が返した値でソートする。
- `sortBy()` が昇順、 `sortByDescending()` が降順。

### sortWith()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val mutableList = mutableListOf(2, 3, 1)

    mutableList.sortWith(Comparator { a, b ->  b - a})
    println(mutableList)
}
```

```text:実行結果
[3, 2, 1]
```

- `Comparator` を指定してソートする。

# Map 以下のメソッド
## Map のメソッド
### all()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.all { it.key is String })
    println(map.all { it.key.contains("o") })
}
```

```text:実行結果
true
false
```

- 全てのエントリに対してラムダ式が `true` を返した場合に `true` を返す。

### any()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.any { it.key.contains("o") })
    println(map.any { it.key.isEmpty() })
}
```

```text:実行結果
true
false
```

- いずれかのエントリに対してラムダ式が `true` を返した場合に `true` を返す。

### contains()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.contains("one"))
    println(map.contains("ONE"))
}
```

```text:実行結果
true
false
```

- 指定したキーのエントリを持つか確認する。
- `containsKey()` と同じ。

### containsKey()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.containsKey("one"))
    println(map.containsKey("ONE"))
}
```

```text:実行結果
true
false
```

- 指定したキーのエントリを持つか確認する。
- `contains()` と同じ。

### containsValue()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.containsValue("one"))
    println(map.containsValue("ONE"))
}
```

```text:実行結果
false
true
```

- 指定したバリューのエントリを持つか確認する。

### count()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.count())
    println(map.count { it.key.contains("t") })
}
```

```text:実行結果
3
2
```

- エントリの数を取得する。
- ラムダ式でカウントするエントリを絞り込むことができる。

### filter(), filterNot()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.filter { it.key.contains("t") })
    println(map.filterNot { it.key.contains("t") })
}
```

```text:実行結果
{two=TWO, three=THREE}
{one=ONE}
```

- `filter()` はラムダ式で指定した条件に一致するエントリだけを抽出する。
- `filterNot()` はラムダ式で指定した条件に一致しないエントリだけを抽出する。
- ラムダ式には各エントリが渡される。

### filterKeys(), filterValues()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.filterKeys { key -> key.contains("o") })
    println(map.filterValues { value -> value.contains("T") })
}
```

```text:実行結果
{one=ONE, two=TWO}
{two=TWO, three=THREE}
```

- ラムダ式で指定した条件に一致するエントリだけを抽出する。
- `filterKeys()` は、ラムダ式に各エントリのキーが渡される。
- `filterValues()` は、ラムダ式に各エントリのバリューが渡される。

### flatMap()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.flatMap { listOf(it.key, it.value) })
}
```

```text:実行結果
[one, ONE, two, TWO, three, THREE]
```

- 各要素ごとにラムダ式がコールされる。
- そして、各ラムダ式のコールで返された `Iterable` を１つの `List` に詰めて返す。

### forEach()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    map.forEach { println("key=${it.key}, value=${it.value}") }
}
```

```text:実行結果
key=one, value=ONE
key=two, value=TWO
key=three, value=THREE
```

- 各エントリを処理する。

### getOrElse()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.getOrElse("one", {"DEFAULT"}))
    println(map.getOrElse("nine", {"DEFAULT"}))
}
```

```text:実行結果
ONE
DEFAULT
```

- 指定したキーに該当するエントリが存在しない場合は、ラムダ式が返す値をデフォルト値として返す。

### isEmpty(), isNotEmpty()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf<String, String>()

    println(map.isEmpty())
    println(map.isNotEmpty())
}
```

```text:実行結果
true
false
```

- `Map` 空かどうか確認できる。

### none()
```kotlin
fun main(args: Array<String>) {
    val map1 = mapOf("one" to "ONE")
    val map2 = mapOf<String, String>()

    println(map1.none())
    println(map2.none())

    println(map1.none {it.key == "two"})
}
```

```text:実行結果
false
true
true
```

- `Map` が空であることを確認する。
- ラムダ式を渡すことで、条件を絞ることができる。

### orEmpty()
```kotlin
fun main(args: Array<String>) {
    val map1 = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")
    val map2: Map<String, String>? = null

    println(map1.orEmpty())
    println(map2.orEmpty())
}
```

```text:実行結果
{one=ONE, two=TWO, three=THREE}
{}
```

- `Map` の型が `null` 可で、かつ実際に `null` だった場合は空の `Map` を返す。
- そうでない場合は、自分自身をそのまま返す。

### map(), mapNotNull()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.map { if (it.key == "two") null else "${it.key}=${it.value}" })
    println(map.mapNotNull { if (it.key == "two") null else "${it.key}=${it.value}" })
}
```

```text:実行結果
[one=ONE, null, three=THREE]
[one=ONE, three=THREE]
```

- 各エントリごとにラムダ式がコールされる。
- ラムダ式が返した値が `List` に詰められて返される。
- `map()` は、 `null` が返された場合にそれをそのまま `List` に詰める。
- `mapNotNull()` は、 `null` をスキップする。

### mapKeys(), mapValues()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.mapKeys { "<${it.key}>" })
    println(map.mapValues { "<${it.value}>" })
}
```

```text:実行結果
{<one>=ONE, <two>=TWO, <three>=THREE}
{one=<ONE>, two=<TWO>, three=<THREE>}
```

- 各エントリごとにラムダ式がコールされる。
- `mapKeys()` は、各エントリのキーがラムダ式の返した値で置き換えられる。
- `mapValues()` は、各エントリのバリューがラムダ式の返した値で置き換えられる。

### maxBy(), minBy()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.maxBy { it.key })
    println(map.minBy { it.key })
}
```

```text:実行結果
two=TWO
one=ONE
```

- ラムダ式が返した値で各エントリの大小を比較し、最大最小のエントリを取得する。

### maxWith(), minWith()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    val comparator = Comparator<Map.Entry<String, String>> { a, b -> a.key.compareTo(b.key) }

    println(map.maxWith(comparator))
    println(map.minWith(comparator))
}
```

```text:実行結果
two=TWO
one=ONE
```

- `Comparator` で比較方法を指定して最大、最小のエントリを取得する。

### plus()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(map.plus(mapOf("four" to "FOUR")))
    println(map.plus("five" to "FIVE"))
    println(map.plus(listOf("six" to "SIX")))

    println(map + ("seven" to "SEVEN"))
}
```

```text:実行結果
{one=ONE, two=TWO, three=THREE, four=FOUR}
{one=ONE, two=TWO, three=THREE, five=FIVE}
{one=ONE, two=TWO, three=THREE, six=SIX}
{one=ONE, two=TWO, three=THREE, seven=SEVEN}
```

- `Map`, `Pair`, `List<Pair>` を渡すことで、要素を追加した新しい `Map` を返す。
- `+` 演算子に置き換えることもできる。

### toList()
```kotlin
fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")
    val list: List<Pair<String, String>> = map.toList()
    
    println(list)
}
```

```text:実行結果
[(one, ONE), (two, TWO), (three, THREE)]
```

- `Map<K, V>` を `List<Pair<K, V>>` に変換する。

### toProperties()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")
    val properties: Properties = map.toProperties()

    println(properties)
}
```

```text:実行結果
{two=TWO, one=ONE, three=THREE}
```

- `java.util.Properties` に変換する。

### toSortedMap()
```kotlin
import java.util.*

fun main(args: Array<String>) {
    val map = mapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")
    val sortedMap: SortedMap<String, String> = map.toSortedMap()

    println(sortedMap)
}
```

```text:実行結果
{one=ONE, three=THREE, two=TWO}
```

- `java.util.SortedMap` に変換する。


## MutableMap のメソッド
### getOrPut
```kotlin
fun main(args: Array<String>) {
    val mutableMap = mutableMapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    println(mutableMap.getOrPut("one", {"DEFAULT"}))
    println(mutableMap)
    println(mutableMap.getOrPut("four", {"DEFAULT"}))
    println(mutableMap)
}
```

```text:実行結果
ONE
{one=ONE, two=TWO, three=THREE}
DEFAULT
{one=ONE, two=TWO, three=THREE, four=DEFAULT}
```

- 指定したキーに該当するエントリが存在しない場合、ラムダ式が返した値を返す。
- さらに、指定したキーとラムダ式が返した値でエントリが追加される。

### putAll
```kotlin
fun main(args: Array<String>) {
    val mutableMap = mutableMapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    mutableMap.putAll(mapOf("four" to "FOUR", "five" to "FIVE"))
    println(mutableMap)

    mutableMap.putAll(listOf("six" to "SIX"))
    println(mutableMap)
}
```

```text:実行結果
{one=ONE, two=TWO, three=THREE, four=FOUR, five=FIVE}
{one=ONE, two=TWO, three=THREE, four=FOUR, five=FIVE, six=SIX}
```

- `Map` または `Pair` を持ったコレクションを全てエントリとして追加する。

### plusAssign
```kotlin
fun main(args: Array<String>) {
    val mutableMap = mutableMapOf("one" to "ONE", "two" to "TWO", "three" to "THREE")

    mutableMap.plusAssign(mapOf("four" to "FOUR"))
    mutableMap.plusAssign("five" to "FIVE")
    mutableMap.plusAssign(listOf("six" to "SIX"))

    mutableMap += "seven" to "SEVEN"

    println(mutableMap)
}
```

```text:実行結果
{one=ONE, two=TWO, three=THREE, four=FOUR, five=FIVE, six=SIX, seven=SEVEN}
```

- `putAll()` とだいたい同じ。
- `Pair` 単独で指定可能だったり、 `+=` で置き換え可能だったりする点が異なる。



# 参考
- [kotlin-rev-solution/keyword-for-kotlin.md at master · yyYank/kotlin-rev-solution](https://github.com/yyYank/kotlin-rev-solution/blob/master/docs/keyword-for-kotlin.md#to)
- [Generics - Kotlin Programming Language](https://kotlinlang.org/docs/reference/generics.html#variance)