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

  • 89
    Like
  • 2
    Comment

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

Kotlin のコレクション

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

特徴

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

コレクションの種類

インターフェースの関係

kotlin.collections.png

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

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

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

読み取り専用とイミュータブルの違い

Twitter で指摘を受けたので修正します(完全に勘違いしてました、ありがとうございます)。

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

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

    mutableList.add(9)

    println(mutableList)
    println(list)
}
実行結果
[1, 2, 3, 9]
[1, 2, 3, 9]

MutableListList を継承しているので、 MutableListList の変数に代入することができる。
結果、 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

コレクションの生成

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 を生成する

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)
}
実行結果
[null, 1, 2, 3, null]
[1, 2, 3]
  • listOfNotNull() メソッドを使うと、 null を取り除いたコレクションが生成される。

書き込み可能なコレクションを生成する

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 標準のコレクションを生成する

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}")
}
実行結果
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

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])
    }
}
実行結果
0..2
1
2
3
  • Array または Collection に定義されているプロパティ。
  • コレクションのインデックス範囲を表す IntRange オブジェクトが格納されている。
  • indicesindex の複数形。

lastIndex

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

    println(list.lastIndex)
}
実行結果
2
  • Array または List に定義されているプロパティ。
  • コレクションの最後のインデックスを取得できる。

特定のルールで命名されているメソッド

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

To:処理結果を書き込み可能なコレクションに追加するメソッド

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

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

    println(result)
}
実行結果
[<9>, <1>, <2>, <3>, <4>, <5>]
  • 末尾に To がついたメソッドには、書き込み可能なコレクションを渡すことができる。
  • 処理結果は、引数で渡した書き込み可能なコレクションに追加される。

Indexed:繰り返し処理にループインデックスも渡す

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

    iterable.forEachIndexed { index, value -> println("[$index] = $value") }
}
実行結果
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
  • メソッド名に Indexed が含まれるメソッドは、ラムダ式にループインデックスが渡される。

メソッド逆引き

Stream API のあれ、 Kotlin のコレクションだとどれ?

Java Kotlin Collections
Stream.allMatch() Iterable.all(), Map.all()
Stream.anyMatch() Iterable.any(), Map.any()
Stream.count() Iterable.count(), Map.count()
Stream.distinct() Iterable.distinct()
Stream.filter() Iterable.filter(), Map.filter()
Stream.findFirst() Iterable.first(), Iterable.firstOrNull()
Stream.flatMap() Iterable.flatMap(), Map.flatMap()
Stream.forEach() Iterable.forEach(), Map.forEach()
Stream.limit() Iterable.take()
Stream.map() Iterable.map(), Map.map()
Stream.max() Iterable.max(), Map.maxBy()
Stream.min() Iterable.min(), Map.minBy()
Stream.noneMatch() Iterable.none(), Map.none()
Stream.peek() なし?
Stream.reduce() Iterable.reduce()
Stream.sorted() Iterable.sorted()
Stream.skip() なし?
Stream.collect(toList()) Iterable.toList(), Map.toList()
Stream.collect(toMap()) Iterable.toMap()
Stream.collect(toSet()) Iterable.toSet()
Stream.collect(joining()) Iterable.joinToString()
Stream.collect(partitioningBy()) Iterable.partition()
Stream.collect(groupingBy()) Iterable.groupBy()
Stream.collect(reducing()) Iterable.fold()
IntStream.sum() Iterable.sum()
IntStream.average() Iterable.average()

Iterable 以下のメソッド

Iterable のメソッド

all()

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

    println(iterable.all { it < 4 })
    println(iterable.all { it < 3 })
}
実行結果
true
false
  • 全ての要素がラムダ式で指定した条件に一致する場合に true を返す。

any()

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

    println(iterable.any { it < 4 })
    println(iterable.any { it < 0 })
}
実行結果
true
false
  • いずれかの要素がラムダ式で指定した条件に一致する場合に true を返す。

associate()

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

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

    println(map)
}
実行結果
{1=10, 2=20, 3=30}
  • 各要素ごとに Pair を返すことで、 Map に変換した結果を取得できる。

associateBy()

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

    val map = iterable.associateBy { it*10 }

    println(map)
}
実行結果
{10=1, 20=2, 30=3}
  • 各要素に対してラムダ式が実行され、キー:バリューラムダ式が返した値:各要素のもとの値 となる Map が返される。

average()

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

    val average = iterable.average()

    println(average)
}
実行結果
2.0
  • Iterable の各要素の平均値を取得する。
  • このメソッドは、 Iterable の型引数が IntFloat など数値計算が可能な型の場合にのみ使用できる。
  • Iterable<String> で使用しようとすると、コンパイルエラーになる。

contains()

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

    println(iterable.contains(2))
    println(iterable.contains(4))
}
実行結果
true
false
  • 指定した要素が Iterable 内に存在するか確認する。

count()

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

    println(iterable.count())
    println(iterable.count {it % 2 == 1})
}
実行結果
3
2
  • 要素数を取得できる。
  • boolean を返すラムダ式を引数に渡すことで、条件に一致した要素の数だけをカウントできる。

distinct()

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

    println(iterable.distinct())
}
実行結果
[1, 2, 3]
  • 重複する要素を削除した結果を返す。

distinctBy()

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

    println(iterable.distinctBy { it.length })
}
実行結果
[foo, fizz]
  • 重複を判断すための条件を、ラムダ式で指定する。
  • ラムダ式が返した値が等しい要素は重複と判断される。

drop()

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

    println(iterable.drop(2))
}
実行結果
[3, 4, 5]
  • 引数で指定した数だけ先頭から要素を削除して、残った要素をコレクションで返す。

dropWhile()

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

    println(iterable.dropWhile { it != 4 })
}
実行結果
[4, 5]
  • ラムダ式が true を返すまでの要素を削除して、残った要素をコレクションで返す。

elementAt()

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

    println(iterable.elementAt(2))
}
実行結果
3
  • 指定したインデックスの要素を取得する。
  • インデックスが範囲外だった場合は IndexOutOfBoundsException がスローされる。

elementAtOrElse()

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

    println(iterable.elementAtOrElse(0, { it * 10 }))
    println(iterable.elementAtOrElse(5, { it * 10 }))
}
実行結果
1
50
  • 指定したインデックスが範囲外だった場合に返す値を、第二引数のラムダ式で指定する。

elementAtOrNull()

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

    println(iterable.elementAtOrNull(0))
    println(iterable.elementAtOrNull(5))
}
  • 指定したインデックスが範囲外だった場合に null を返す。

filter()

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

    println(iterable.filter { it % 2 != 0 })
}
実行結果
[1, 3]
  • ラムダ式で指定した条件に一致する要素だけを抽出してコレクションで返す。

filterIsInstance()

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

    println(iterable.filterIsInstance<Number>())
    println(iterable.filterIsInstance(String::class.java))
}
実行結果
[1, 2.4]
  • 型パラメータで指定した型と互換のあるインスタンスだけを抽出してコレクションで返す。
  • 引数に Class オブジェクトを渡すことで型を指定することもできる。

filterNot()

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

    println(iterable.filterNot { it % 2 == 0 })
}
実行結果
[1, 3, 5]
  • ラムダ式で指定した条件に一致しない要素だけを抽出してコレクションで返す。

filterNotNull()

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

    println(iterable.filterNotNull())
}
実行結果
[1, 3, 5]
  • null 要素を取り除いたコレクションで返す。

find()

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 })
}
実行結果
2
null
  • ラムダ式で指定した条件に一致した最初の要素を取得する。
  • 条件に一致する要素が存在しない場合は null を返す。

findLast()

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 })
}
実行結果
4
null
  • ラムダ式で指定した条件に一致した最後の要素を取得する。
  • 条件に一致する要素が存在しない場合は null を返す。

first()

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 })
}
実行結果
1
2
Exception in thread "main" java.util.NoSuchElementException: No element matching predicate was found.
  • 先頭の要素を取得する。
  • ラムダ式で条件を絞り込める。
  • 該当する要素が存在しない場合は例外がスローされる。

firstOrNull()

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 })
}
実行結果
1
2
null
  • 先頭の要素を取得する。
  • ラムダ式で条件を絞り込める。
  • 該当する要素が存在しない場合は null が返される。

last()

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 })
}
実行結果
5
4
Exception in thread "main" java.util.NoSuchElementException: Collection doesn't contain any element matching the predicate.
  • 最後の要素を取得する。
  • 引数のラムダ式で、取得する条件を指定できる。
  • 対応する要素が存在しない場合は、例外がスローされる。

lastOrNull()

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 })
}
実行結果
5
4
null
  • 最後の要素を取得する。
  • 引数のラムダ式で、取得する条件を指定できる。
  • 対応する要素が存在しない場合は、 null が返される。

flatMap()

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 })
}
実行結果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
  • ラムダ式が返した Iterable を連結して返す。

flatten()

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())
}
実行結果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 入れ子の Iterable を、単一の Iterable に詰め替え直す(フラットにする)。

fold()

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

    println(iterable.fold("Z", { buf, value -> buf + value }))
}
実行結果
Zabc
  • 第一引数で初期値を指定する。
  • ラムダ式が各要素ごとにコールされる。
    • 第一引数には、初期値で指定した値が最初に渡され、以後は前回ラムダ式が返した値が渡される。
    • 第二引数には、 Iterable の各要素が渡される。

forEach()

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

    iterable.forEach { println(it) }
}
実行結果
1
2
3
  • 各要素を処理する。

groupBy()

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)
}
実行結果
{奇数=[1, 3, 5, 7], 偶数=[2, 4, 6]}
{奇数=[<1>, <3>, <5>, <7>], 偶数=[<2>, <4>, <6>]}
  • ラムダ式が返した値ごとに各要素を分類して、 Map 詰めて返す。
  • 第二引数にラムダ式を追加すれば、各要素を任意の値に変換できる。

indexOfFirst()

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

    println(iterable.indexOfFirst { it % 2 == 0 })
}
実行結果
1
  • 指定したラムダ式の条件に一致する最初のインデックスを返す。

indextOfLast()

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

    println(iterable.indexOfLast { it % 2 == 0 })
}
実行結果
3
  • 指定したラムダ式の条件に一致する最後のインデックスを返す。

intersect()

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)
}
実行結果
[2, 3, 5]
  • 引数で指定した Iterable と重複する要素だけを抽出して、 Set に詰めて返す。

joinTo()

基本

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

    iterable.joinTo(buffer)

    println(buffer)
}
実行結果
1, 2, 3, 4, 5
  • 各要素を連結した文字列を、指定した Appendable に設定する。
  • デフォルトでは、各要素を半角カンマ区切りで連結した文字列が設定される。

連結方法を調整する

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)
}
実行結果
{<1> - <2> - <3> - (ry}
引数 説明 デフォルト値
separator 区切り文字 ,
prefix 先頭に設定する文字列 ""
postfix 末尾に設定する文字列 ""
limit 連結する要素の最大値 -1
truncated 省略された要素の表記 ...
transform 各要素を任意の値に変換する処理 null

joinToString()

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

    println(iterable.joinToString())
}
実行結果
1, 2, 3, 4, 5
  • joinTo() メソッドの結果を Appendable に設定するのではなく、そのまま文字列として返却する。
  • separator などの引数は、 joinTo() と同じように指定できる。

map()

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

    println(iterable.map { it * 10 })
}
実行結果
[10, 20, 30, 40, 50]
  • 各要素をラムダ式が返した値で置き換えた新しいコレクションを返す。

mapNotNull()

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

    println(iterable.mapNotNull { if (it % 2 == 0) it else null })
}
実行結果
[2, 4]
  • 各要素をラムダ式が返した値で置き換えた新しいコレクションを返す。
  • ただし、ラムダ式が null を返した場合はスキップされる。

max(), min()

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

    println(iterable.max())
    println(iterable.min())
}
実行結果
5
1
  • max() で最大の要素を取得する。
  • min() で最小の要素を取得する。
  • 要素は Comparable を実装している必要がある。

maxBy(), minBy()

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

    println(iterable.maxBy { it.length })
    println(iterable.minBy { it.length })
}
実行結果
xxxx
zz
  • ラムダ式が返した値で大小を比較する。
  • maxBy() で最大、 minBy() で最小を取得する。

maxWith(), minWith()

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 }))
}
実行結果
1
5
  • 引数に Comparator を渡すことで、大小比較の方法を指定できる。
  • maxWith() で最大、 minWith() で最小を取得する。

minus()

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)
}
実行結果
[1, 2, 2, 3, 4, 5]
[1, 1, 3]
[1, 1, 3]
  • 指定した要素を取り除いたコレクションを返す。
  • 要素1つだけを引数に渡した場合は、該当する最初の要素だけが除去される。
  • IterableList, Sequence を渡すこともできる。
  • - 演算子で書き換えることもできる。

plus()

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)
}
実行結果
[1, 2, 3, 6]
[1, 2, 3, 3, 5]
[1, 2, 3, 3, 5]
  • 指定した要素を追加したコレクションを返す。
  • 他のコレクションを指定することもできる。
  • + 演算子で書き換えることもできる。

none()

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})
}
実行結果
false
true
false
true
  • 要素を持たない場合に true を返す。
  • ラムダ式で条件を絞り込める。

partition()

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)
}
実行結果
([2, 4], [1, 3, 5])
  • ラムダ式で指定した条件で要素を二分して Pair で返す。
  • 条件が true となった要素が first に、 false となった要素が second にセットされる。

reduce()

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

    println(iterable.reduce {tmp, value ->
        println("tmp=$tmp, value=$value")
        tmp + ":" + value
    })
}
実行結果
tmp=a, value=b
tmp=a:b, value=c
a:b:c
  • ラムダ式による変換を積み重ねながら各要素を処理する。
  • ラムダ式の第一引数には、初回は先頭要素が渡され、以後は前回ラムダ式が返した値が渡される。

requireNoNulls()

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

    println(iterable.requireNoNulls())
}
実行結果
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()

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

    println(iterable.reversed())
}
実行結果
[4, 3, 2, 1]
  • 中身を逆順序にしたコレクションを返す。

single()

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

    println(iterable1.single())
    println(iterable2.single {it == 3})
}
実行結果
9
3
  • コレクションが持つ唯一の要素を取得する。
  • ラムダ式で条件を絞ることもできる。
  • 以下のように、該当する要素が0または2件以上存在する場合は例外がスローされる。
fun main(args: Array<String>) {
    val iterable = listOf(1, 2, 3, 4)

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

singleOrNull()

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())
}
実行結果
9
4
null
  • 基本は single() と同じだが、該当する要素が存在しない場合は null を返す点が異なる。

sorted(), sortedDescending()

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

    println(iterable.sorted())
    println(iterable.sortedDescending())
}
実行結果
[1, 2, 3, 4]
[4, 3, 2, 1]
  • 要素をソートしたコレクションを返す。
  • sorted() は昇順ソート、 sortedDescending() は降順ソート。

sortedBy(), sortedByDescending()

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

    println(iterable.sortedBy { it * -1 })
    println(iterable.sortedByDescending { it * -1 })
}
実行結果
[4, 3, 2, 1]
[1, 2, 3, 4]
  • ソートの判定に使用する値を返すラムダ式を渡すことで、ソート方法を調整できる。
  • sortedBy() は昇順ソート、 sortedByDescending() は降順ソート。

sortedWith()

import java.util.*

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

    println(iterable.sortedWith(Comparator { left, right -> right - left }))
}
実行結果
[4, 3, 2, 1]
  • ソート方法を Comparator で実装して渡す。

subtract()

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))
}
実行結果
[1, 5]
  • 指定したコレクションに存在しない要素だけを抽出して Set で返す。
  • 重複は除去される。

sum()

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

    println(iterable.sum())
}
実行結果
6
  • コレクションの各要素の合計を返す。
  • コレクションの要素は数値計算が可能な型である必要がある。

sumBy()

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

    println(iterable.sumBy { it * 10 })
}
実行結果
60
  • ラムダ式が返した値で合計を計算する。

sumByDouble()

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

    println(iterable.sumByDouble { it * 1.5 })
}
実行結果
9.0
  • ラムダ式が返す Double 値で合計を算出する。

take()

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

    println(iterable.take(3))
}
実行結果
[1, 2, 3]
  • 先頭から指定した数だけ要素を取得して List で返す。

takeWhile()

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

    println(iterable.takeWhile { it < 5 })
}
実行結果
[1, 2, 3, 4]
  • 先頭から、ラムダ式で指定した条件が満たされなくなるまで要素を取得して List で返す。

toCollection()

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

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

    iterable.toCollection(result)

    println(result)
}
実行結果
[9, 1, 2, 3]
  • 指定した MutableCollection に要素を追加する。

toHashSet()

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)
}
実行結果
[1, 2, 3]
  • HashSet に変換する。

toList()

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

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

    println(list)
}
実行結果
[1, 2, 3]
  • List に変換する。

toMap()

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)
}
実行結果
{foo=FOO, bar=BAR}
{fizz=FIZZ, foo=FOO, bar=BAR}
  • Iterable<Pair<K, V>>Map<K, V> に変換する。
  • 引数に MutableMap を渡すと、その Map に追加される。

toMutableList()

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

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

    println(result)
}
実行結果
[1, 2, 3]
  • MutableList に変換する。

toMutableSet()

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

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

    println(result)
}
実行結果
[1, 2, 3]
  • MutableSet に変換する。

toSet()

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

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

    println(result)
}
実行結果
[1, 2, 3]
  • Set に変換する。

toSortedSet()

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)
}
実行結果
[1, 2, 3, 4]
  • SortedSet に変換する。

union()

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)
}
実行結果
[1, 2, 3, 4, 5, 6]
  • 2つの Iterable の要素を合計して Set で返す。

unzip()

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)
}
実行結果
([one, two, three], [1, 2, 3])
  • List<Pair<T, U>>Pair<List<T>, List<U>> に変換する。

withIndex()

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}") }
}
実行結果
index=0, value=1
index=1, value=2
index=2, value=3
index=3, value=4
index=4, value=5
  • Iterable<IndexedValue<T>> に変換する。

zip()

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)
}
実行結果
[(1, one), (2, two), (3, three)]
[(1, 1.1), (2, 2.2)]
  • 2つの Iterable(または Array) の各要素を1つの Pair にして、 List に詰めて返す。
  • 要素数が合わない場合は、少ないほうに合わせられる。
  • 以下のようにラムダ式で各要素を変換することもできる。
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)
}
実行結果
[one(1), two(2), three(3)]
[12, 24]

Collection のメソッド

containsAll()

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))
}
実行結果
true
false
  • 指定したコレクションに含まれる全ての要素を持つかどうかを確認する。

isNotEmpty()

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

    println(collection1.isEmpty())
    println(collection2.isEmpty())
}
実行結果
false
true
  • コレクションがからかどうかを確認する。

orEmpty()

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

    println(collection1.orEmpty())
    println(collection2.orEmpty())
}
実行結果
[1, 2, 3, 4]
[]
  • コレクションの型が null 可で、かつ実際 null だった場合は空のコレクションを返す。
  • そうでない場合は、自分自身をそのまま帰す。

to***Array()

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

    val array: IntArray = collection.toIntArray()

    array.forEach { println(it) }
}
実行結果
1
2
3
4
  • ***Array に変換する。
  • Boolean, Byte, Char, Double, Float, Int, Long, Short がある。

toTypedArray()

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

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

    array.forEach { println(it) }
}
実行結果
1
2
3
4
  • Array<T> に変換する。

List のメソッド

asReversed()

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")
}
実行結果
[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()

基本

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 }))
}
実行結果
4
-7
-3
4
  • バイナリサーチで指定した要素を検索し、該当した場所のインデックスを返す。
    • 要素が見つからなかった場合は負数が返される。
  • List はあらかじめソートされている必要がある。
    • ソートされていない場合はデタラメな値を返す。
  • 第二引数(fromIndex)と第三引数(toIndex)で、検索の範囲を指定できる。
  • comparator で、要素の比較方法を指定できる。

binarySearchBy()

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

    println(list.binarySearchBy("Thank you", selector = { "Thank $it" }))
}
実行結果
3
  • 各要素を selector で変換して、その値に一致する項目を検索し、該当するインデックスを返す。
  • List はソートされている必要がある。

component*()

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())
}
実行結果
one
two
three
four
five
  • 1~5番目までの要素を取得する。
  • 使いドコロは・・・不明。

dropLast()

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

    println(list.dropLast(2))
}
実行結果
[1, 2, 3]
  • 指定した数だけ、要素を後ろから削除した結果を List で返す。

dropLastWhile()

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

    println(list.dropLastWhile { it > 2 })
}
実行結果
[1, 2]
  • ラムダ式が true を返す間、末尾から要素を削除し、残った要素を List に詰めて返す。

foldRight()

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

    println(list.foldRight("Z", { value, buf -> buf + value }))
}
実行結果
Zcba
  • 末尾から順番に要素を処理し、結果を蓄積していく。
  • ラムダ式の第二引数には、初回は第一引数で渡した初期値が渡され、二回目以降は前回ラムダ式が返した値が渡される。

  • 第一引数で初期値を指定する。

  • ラムダ式が各要素ごとにコールされる。

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

getOrElse()

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

    println(list.getOrElse(0, { 9 }))
    println(list.getOrElse(4, { 9 }))
}
実行結果
1
9
  • 指定したインデックスの要素を取得する。
  • インデックスが範囲外の場合は、ラムダ式が返す値をデフォルト値として返す。

getOrNull()

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

    println(list.getOrNull(0))
    println(list.getOrNull(4))
}
実行結果
1
null
  • 指定したインデックスの要素を取得する。
  • インデックスが範囲外の場合は、 null を返す。

reduceRight()

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

    println(list.reduceRight { value, tmp ->
        println("value=$value, tmp=$tmp")
        tmp + ":" + value
    })
}
実行結果
value=b, tmp=c
value=a, tmp=c:b
c:b:a
  • ラムダ式による変換を積み重ねながら各要素を末尾から順番に処理する。
  • ラムダ式の第一引数には、初回は末尾の要素が渡され、以後は前回ラムダ式が返した値が渡される。

slice()

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))
}
実行結果
[2:three, 3:four, 4:five]
[1:two, 3:four, 4:five]
  • インデックスの指定で要素を抜き取る。
  • IntRange を使うと、範囲指定で要素を抜き取ることができる。
  • Iterable を使うと、指定したインデックスの要素だけを抜き取ることができる。

takeLast()

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

    println(list.takeLast(2))
}
実行結果
[4, 5]
  • 指定した数だけ末尾から要素を取得し、 List にして返す。

takeLastWhile()

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

    println(list.takeLastWhile { it > 2 })
}
実行結果
[3, 4, 5]
  • ラムダ式が true を返す間、末尾から順番に要素を取得し、 List に詰めて返す。

MutableIterable のメソッド

removeAll()

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

    mutableIterable.removeAll { it == 3 }

    println(mutableIterable)
}
実行結果
[1, 2, 1, 2]
  • ラムダ式で指定した条件に一致する要素を全て削除する。

retainAll()

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

    mutableIterable.retainAll { it == 3 }

    println(mutableIterable)
}
実行結果
[3, 3]
  • ラムダ式で指定した条件に一致する要素だけを残し、残りを全て削除する。

MutableCollection のメソッド

addAll()

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

    mutableCollection.addAll(iterable)

    println(mutableCollection)
}
実行結果
[1, 2, 3, 7, 8, 9]
  • 指定したコレクションの要素を全て追加する。

minusAssign()

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)
}
実行結果
[1, 3, 5]
[1, 3]
  • コレクションまたは単独で指定した要素を削除する。
  • -= で置き換えることができる。

plusAssign()

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)
}
実行結果
[1, 2, 3, 7, 8]
[1, 2, 3, 7, 8, 9]
  • コレクションまたは単独で指定した要素を追加する。
  • += で置き換えることができる。

remove()

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

    mutableCollection.remove(2)

    println(mutableCollection)
}
実行結果
[1, 3]
  • 指定した要素を削除する。

MutableList のメソッド

reverse()

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

    mutableList.reverse()

    println(mutableList)
}
実行結果
[3, 2, 1]
  • 順序を逆にする。

sort(), sortDescending()

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

    mutableList.sort()
    println(mutableList)

    mutableList.sortDescending()
    println(mutableList)
}
実行結果
[1, 2, 3]
[3, 2, 1]
  • 要素をソートする。
  • sort() が昇順、 sortDescending() が降順。

sortBy(), sortByDescending()

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

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

    mutableList.sortByDescending { it.length }
    println(mutableList)
}
実行結果
[c, bb, aaa]
[aaa, bb, c]
  • ラムダ式が返した値でソートする。
  • sortBy() が昇順、 sortByDescending() が降順。

sortWith()

import java.util.*

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

    mutableList.sortWith(Comparator { a, b ->  b - a})
    println(mutableList)
}
実行結果
[3, 2, 1]
  • Comparator を指定してソートする。

Map 以下のメソッド

Map のメソッド

all()

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") })
}
実行結果
true
false
  • 全てのエントリに対してラムダ式が true を返した場合に true を返す。

any()

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() })
}
実行結果
true
false
  • いずれかのエントリに対してラムダ式が true を返した場合に true を返す。

contains()

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"))
}
実行結果
true
false
  • 指定したキーのエントリを持つか確認する。
  • containsKey() と同じ。

containsKey()

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"))
}
実行結果
true
false
  • 指定したキーのエントリを持つか確認する。
  • contains() と同じ。

containsValue()

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"))
}
実行結果
false
true
  • 指定したバリューのエントリを持つか確認する。

count()

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") })
}
実行結果
3
2
  • エントリの数を取得する。
  • ラムダ式でカウントするエントリを絞り込むことができる。

filter(), filterNot()

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") })
}
実行結果
{two=TWO, three=THREE}
{one=ONE}
  • filter() はラムダ式で指定した条件に一致するエントリだけを抽出する。
  • filterNot() はラムダ式で指定した条件に一致しないエントリだけを抽出する。
  • ラムダ式には各エントリが渡される。

filterKeys(), filterValues()

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") })
}
実行結果
{one=ONE, two=TWO}
{two=TWO, three=THREE}
  • ラムダ式で指定した条件に一致するエントリだけを抽出する。
  • filterKeys() は、ラムダ式に各エントリのキーが渡される。
  • filterValues() は、ラムダ式に各エントリのバリューが渡される。

flatMap()

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) })
}
実行結果
[one, ONE, two, TWO, three, THREE]
  • 各要素ごとにラムダ式がコールされる。
  • そして、各ラムダ式のコールで返された Iterable を1つの List に詰めて返す。

forEach()

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}") }
}
実行結果
key=one, value=ONE
key=two, value=TWO
key=three, value=THREE
  • 各エントリを処理する。

getOrElse()

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"}))
}
実行結果
ONE
DEFAULT
  • 指定したキーに該当するエントリが存在しない場合は、ラムダ式が返す値をデフォルト値として返す。

isEmpty(), isNotEmpty()

fun main(args: Array<String>) {
    val map = mapOf<String, String>()

    println(map.isEmpty())
    println(map.isNotEmpty())
}
実行結果
true
false
  • Map 空かどうか確認できる。

none()

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"})
}
実行結果
false
true
true
  • Map が空であることを確認する。
  • ラムダ式を渡すことで、条件を絞ることができる。

orEmpty()

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())
}
実行結果
{one=ONE, two=TWO, three=THREE}
{}
  • Map の型が null 可で、かつ実際に null だった場合は空の Map を返す。
  • そうでない場合は、自分自身をそのまま返す。

map(), mapNotNull()

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}" })
}
実行結果
[one=ONE, null, three=THREE]
[one=ONE, three=THREE]
  • 各エントリごとにラムダ式がコールされる。
  • ラムダ式が返した値が List に詰められて返される。
  • map() は、 null が返された場合にそれをそのまま List に詰める。
  • mapNotNull() は、 null をスキップする。

mapKeys(), mapValues()

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}>" })
}
実行結果
{<one>=ONE, <two>=TWO, <three>=THREE}
{one=<ONE>, two=<TWO>, three=<THREE>}
  • 各エントリごとにラムダ式がコールされる。
  • mapKeys() は、各エントリのキーがラムダ式の返した値で置き換えられる。
  • mapValues() は、各エントリのバリューがラムダ式の返した値で置き換えられる。

maxBy(), minBy()

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 })
}
実行結果
two=TWO
one=ONE
  • ラムダ式が返した値で各エントリの大小を比較し、最大最小のエントリを取得する。

maxWith(), minWith()

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))
}
実行結果
two=TWO
one=ONE
  • Comparator で比較方法を指定して最大、最小のエントリを取得する。

plus()

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"))
}
実行結果
{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()

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)
}
実行結果
[(one, ONE), (two, TWO), (three, THREE)]
  • Map<K, V>List<Pair<K, V>> に変換する。

toProperties()

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)
}
実行結果
{two=TWO, one=ONE, three=THREE}
  • java.util.Properties に変換する。

toSortedMap()

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)
}
実行結果
{one=ONE, three=THREE, two=TWO}
  • java.util.SortedMap に変換する。

MutableMap のメソッド

getOrPut

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)
}
実行結果
ONE
{one=ONE, two=TWO, three=THREE}
DEFAULT
{one=ONE, two=TWO, three=THREE, four=DEFAULT}
  • 指定したキーに該当するエントリが存在しない場合、ラムダ式が返した値を返す。
  • さらに、指定したキーとラムダ式が返した値でエントリが追加される。

putAll

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)
}
実行結果
{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

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)
}
実行結果
{one=ONE, two=TWO, three=THREE, four=FOUR, five=FIVE, six=SIX, seven=SEVEN}
  • putAll() とだいたい同じ。
  • Pair 単独で指定可能だったり、 += で置き換え可能だったりする点が異なる。

参考