Help us understand the problem. What is going on with this article?

Kotlin の Collection まとめ ~List編~

はじめに

Java に比べた Kotlin のメリットとして、標準ライブラリがサポートしている Collection のメソッドがあります。
かゆいところに手が届くものがいろいろあって便利です。

今回、Listをベースに Kotlin 公式 に記載されているプロパティ・メソッドを試してまとめてみました。

※ 全てを記載しているわけではありません。

宣言

最初にListの宣言をまとめておきます。
不変のリストは listOf
可変のリストは mutableListOf
で宣言します。

val ms = mutableListOf("穂乃果", "ことり", "海未")
val first = listOf("花陽", "凛", "真姫")
val seitokai = listOf("絵里", "希")
ms.addAll(first)
ms.add("にこ")
ms.addAll(seitokai)

// エラー
// seitokai.add("にこ")

println(ms)
出力
[穂乃果, ことり, 海未, 花陽, 凛, 真姫, にこ, 絵里, 希]

ちなみに null を除いた List も生成できます。

val list = listOfNull("穂乃果", null, "ことり", null, "海未")

println(list)
出力
[穂乃果, ことり, 海未]

parameters

size

List のサイズを返します

val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
println(ms.size)
出力
9

Function

List が持つ関数です

contains

collection が引数の値を要素として持っていれば true を返します

val seconds = listOf("穂乃果", "ことり", "海未")
println(seconds.contains("穂乃果"))
出力
true

containsAll

指定したcollectionが持つ要素を全て持っていれば true を返します。

val seconds = listOf("穂乃果", "ことり", "海未")
println(seconds.containsAll(listOf("穂乃果", "ことり")))
println(seconds.containsAll(listOf("穂乃果", "絵里")))
出力
true
false

get

指定したインデックスの要素を取得します。
get(index)[index] は同じです。

val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
println(ms.get(0))
println(ms[0])
出力
穂乃果
穂乃果

indexOf, lastIndexOf

指定した要素がcollection内で初めて登場するインデックスを取得します。
該当するものがない場合は -1 を返します。
lastIndexOf はcollectionの後ろから探査します。

val duplicate = listOf("穂乃果", "ことり", "ことり", "海未")
println(duplicate.indexOf("ことり"))
println(duplicate.indexOf("絵里"))
println(duplicate.lastIndexOf("ことり"))
出力
1
-1
2

isEmpty

指定したcollectionが空なら true を返します。

val emptyList = listOf<String>()
val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
println(emptyList.isEmpty())
println(ms.isEmpty())
出力
true
false

iterator, listIterator

list を iterator, listIterator に変換します。
引数にindexを指定すると、そこから開始します。

val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
val itr = ms.iterator()
val listItr = ms.listIterator(2)
println(itr.next())
println(listItr.previous())
出力
穂乃果
絵里

subList

指定したlistを分割します。

val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
println(ms.subList(0, 3))
出力
[穂乃果, 絵里, ことり]

Extension Properties

indices

指定したlistの範囲(IntRange)を返します。

val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
println(ms.indices)
出力
0..8

lastIndex

指定したlistの最後のインデックスを返します。

val ms = listOf("穂乃果", "絵里", "ことり", "海未", "凛", "真姫", "希", "花陽", "にこ")
println(ms.lastIndex)
出力
8

Extension Functions

all

指定した条件をlist内の全ての要素が満たす場合 true を返します。

val numberList = listOf(1, 2, 3, 4, 5)
println(numberList.all { it < 6 })
println(numberList.all { it < 5 })
出力
true
false

any

指定した条件をlist内のいずれかの要素が満たす場合 true を返します。

val numberList = listOf(1, 2, 3, 4, 5)
println(numberList.any { it > 5 })
println(numberList.any { it > 4 })
出力
false
true

asReversed

指定したlistを逆順にしたlistを返します。

val numberList = listOf(1, 2, 3, 4, 5)
println(numberList.asReversed())
出力
[5, 4, 3, 2, 1]

associate

listの各要素をMapに変換します。
~By は要素をkeyではなくvalueにします。
~To は引数に指定したMapに結果を入れます。
~With は要素をkey、ラムダ式内の結果をvalueにします。

val numberList = listOf(1, 2, 3, 4, 5)
val associateMap = mutableMapOf<Int, Int>()
val associateByMap = mutableMapOf<Int, Int>()
val associateWithMap = mutableMapOf<Int, Int>()

println(numberList.associate { it to it * 10 })
println(numberList.associateBy { it * 10 })
println(numberList.associateTo(associateMap) { it to it * 100 })
println(numberList.associateByTo(associateByMap) { it * 100 })
println(numberList.associateWith { it * 1000 })
println(numberList.associateWithTo(associateWithMap) { it * 1000 })
出力
{1=10, 2=20, 3=30, 4=40, 5=50}
{10=1, 20=2, 30=3, 40=4, 50=5}
{1=100, 2=200, 3=300, 4=400, 5=500}
{100=1, 200=2, 300=3, 400=4, 500=5}
{1=1000, 2=2000, 3=3000, 4=4000, 5=5000}
{1=1000, 2=2000, 3=3000, 4=4000, 5=5000}

binarySearch, binarySearchBy

バイナリサーチで指定した要素のインデックスを返します。
指定した要素が存在しない場合、負の数を返します。
listはソートされている必要があり、ソートされていないと正しい値を返しません。
引数で探査する始点・終点・比較方法などを設定できます。
binarySearchByselector で要素を変換したうえで探査します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.binarySearch(2))
println(numberList.binarySearch(6))
println(numberList.binarySearch(element = 2, fromIndex = 0, toIndex = 3))
println(numberList.binarySearch(element = 2, comparator = Comparator { a, b -> a - b }))
println(numberList.binarySearchBy(2, selector = { it }))
出力
1
-6
1
1
1

chunked

listを引数で指定した数ごとにグループ化します。

val numberList = listOf(1, 2, 3, 4, 5)
println(numberList.chunked(2))
出力
[[1, 2], [3, 4], [5]]

component

指定したインデックスの要素を取得します。
get[] でいい。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.component1())
println(numberList.component2())
出力
1
2

contains, containsAll

listが指定した要素を含んでいれば true を返します。
containsAll は引数にlistを指定します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.contains(2))
println(numberList.contains(6))
println(numberList.containsAll(listOf(1, 3, 4, 5, 2)))
出力
true
false
true

count

指定した条件に一致する要素がいくつあるかを返します。

val numberList = listOf(1, 2, 3, 4, 5)
println(numberList.count { it > 3 })
出力
2

distinct, distinctBy

要素の重複を除外したlistを返します。
distinctBy は指定した条件を重複判定に用います。

val distinctList = listOf(1, 1, 2, 3, 4, 4)
println(distinctList.distinct())
println(distinctList.distinctBy { it > 2 })
出力
[1, 2, 3, 4]
[1, 3]

drop, dropLast, dropWhile, dropLastWhile

指定した数の分、要素を除外したlistを返します。
dropLast は後ろから除外します。
dropWhile は指定した条件を満たす間除外します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.drop(2))
println(numberList.dropLast(2))
println(numberList.dropWhile { it < 2 })
println(numberList.dropLastWhile { it > 2 })
出力
[3, 4, 5]
[1, 2, 3]
[2, 3, 4, 5]
[1, 2]

elementAt, elementAtOrElse, elementAtOrNull

指定したインデックスの要素を取得します。
elementAt でインデックスがlistのサイズを超えた場合は IndexOutOfBoundsException が発生します。
elementAtOrElse は指定したインデックスが範囲外だった場合の返却値をラムダ式で定義できます。
elementAtOrNull は指定したインデックスが範囲外だった場合 null を返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.elementAt(2))
println(numberList.elementAtOrElse(6) { 8 })
println(numberList.elementAtOrNull(6))
出力
3
8
null

filter系

filter

指定した条件に合致する要素のみ残したlistを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.filter { it > 3 })
出力
[4, 5]

filterIndexed, filterIndexedTo

インデックス付きのfilter
filterIndexedTo は引数に指定したlistに結果を入れます。

val numberList = listOf(1, 2, 3, 4, 5)
val filterList = mutableListOf<Int>()

println(numberList.filterIndexed { idx, num -> num > 2 && idx > 3 })

numberList.filterIndexedTo(filterList) { idx, num -> num > 2 && idx > 3 }
println(filterList)
出力
[5]
[5]

filterIsInstance, filterIsInstanceTo

指定する条件がクラスになったfilterです。

val instanceList = listOf(1, "穂乃果", 3.5, true)
val filterList = mutableListOf<Int>()

println(instanceList.filterIsInstance(String::class.java))

instanceList.filterIsInstanceTo(filterList, Int::class.java)
println(filterList)
出力
[穂乃果]
[5]

filterNot, filterNotNull

指定した条件に合致しない要素のみ残したlistを返します。
filterNotNullnull を除外します。

val numberList = listOf(1, 2, 3, 4, 5)
val nullList = listOf(1, null, 3, null)

println(numberList.filterNot { it > 3 })
println(nullList.filterNotNull())
出力
[1, 2, 3]
[1, 3]

find, findLast

指定した条件に合致する最初の要素を返します。
条件に合致する要素がない場合は null を返します。
findLast は後ろから要素を探索します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.find { it > 2 })
println(numberList.find { it > 5 })
println(numberList.findLast { it > 2 })
出力
3
null
5

first, firstOrNull

最初の要素を返します。
ラムダ式を指定した場合は条件に一致する最初の要素を返します。
条件に合致する要素がない場合 NoSuchElementException が発生します。
firstOrNull は条件に合致する要素がない場合 null を返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.first())
println(numberList.first { it > 2 })
println(numberList.firstOrNull { it > 5 })
出力
1
3
null

flatMap, flatten

階層になっているlistを平坦にします。
flatMap はラムダ式で要素の操作ができます。
flatten は単に平坦にします。

val flatMapList = listOf(listOf(1, 2, 3), listOf(4, 5, 6))
println(flatMapList.flatMap { it.map { num -> num * 10 } })
println(flatMapList.flatten())
出力
[10, 20, 30, 40, 50, 60]
[1, 2, 3, 4, 5, 6]

fold, foldRight

引数で指定した値を要素の先頭につけた上で、すべて連結して返します。
foldRight はlistの逆から要素を返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.fold("X") { initial, value -> initial + value })
println(numberList.foldRight("X") { value, initial -> initial + value })
出力
X12345
X54321

forEach, forEachIndexed

listをループします。
ラムダ式内で各要素に対する操作が行えます。
forEachIndexed はインデックス付きでループします。

val numberList = listOf(1, 2, 3, 4, 5)

numberList.forEach { print("${it} ") }
numberList.forEachIndexed { idx, value -> print("${idx}: ${value} ") }
出力
1 2 3 4 5
0: 1 1: 2 2: 3 3: 4 4: 5

getOrElse, getOrNull

指定したインデックスの要素を取得します。
getOrElse はインデックスがlistの範囲外だった際の値を指定できます。
getOrNull はインデックスがlistの範囲外だった際に null を返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.getOrElse(6) { 8 })
println(numberList.getOrNull(6))
出力
8
null

groupBy

要素をグループ化します。
第一引数でグループ化するkeyを、第二引数でグループ化した後のvalueを指定します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.groupBy({ if (it % 2 == 0) "偶数" else "奇数" }, { it + 2 }))
出力
{奇数=[3, 5, 7], 偶数=[4, 6]}

groupingBy

指定した関数オブジェクトで求められる値をkeyとするMapを求めるためのインターフェースを用意します。
eachCount() はkeyで指定した要素がいくつあるかを算出します。

val distinctList = listOf(1, 1, 2, 3, 4, 4)

println(distinctList.groupingBy { it }.eachCount())
出力
{1=2, 2=1, 3=1, 4=2}

ifEmpty

配列が空の場合にラムダ式で指定した値を返します。
空でなければlistをそのまま返します。

val numberList = listOf(1, 2, 3, 4, 5)
val emptyList = listOf<String>()

println(numberList.ifEmpty { 5 })
println(emptyList.ifEmpty { 5 })
出力
[1, 2, 3, 4, 5]
5

indexOf, indexOfFirst, indexOfLast

指定した値に合致する要素のインデックスを返します。
合致する要素がなければ -1 を返します。
indexOfFirst はラムダ式で条件を指定可能。
indexOfLast はlistの後ろから探索。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.indexOf(6))
println(numberList.indexOfFirst { it % 2 == 0 })
println(numberList.indexOfLast { it % 2 == 0 })
出力
-1
1
3

intersect

引数に指定したものと重複する要素を抽出します。
結果は Set になります。

val intersectList = listOf(1, 4)
println(numberList.intersect(intersectList))
出力
[1, 4]

isNotEmpty, isNullOrEmpty

listが空ではないか、nullもしくは空か判定します。

val emptyList = listOf<String>()
val nullObj: List<String>? = null
println(emptyList.isNotEmpty())
println(nullObj.isNullOrEmpty())
出力
false
true

joinTo, joinToString

listの各要素を指定した条件で連結した文字列を返します。
区切り文字だけではなく、prefixなどいろいろな要素が指定できます。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.joinTo(StringBuilder()))
println(numberList.joinToString(
    separator = ".",
    prefix = "{",
    postfix = "}",
    limit = 3,
    truncated = "~",
    transform = { "${it * 2}" }
))
出力
1, 2, 3, 4, 5
{2.4.6.~}

last, lastOrNull

listの最後の値を取得します。
lastIndexOf はlistが空の場合にnullを返します。

val numberList = listOf(1, 2, 3, 4, 5)
val emptyList = listOf<Int>()

println(numberList.last())
println(numberList.lastOrNull())
println(emptyList.lastOrNull())
出力
5
5
null

lastIndexOf

指定した値が最初に登場するインデックスを後ろから探査します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.lastIndexOf(4))
出力
3

map, mapIndexed, mapNotNull

各要素に対して特定の操作を行い、その返却値に値を変えたlistを返します。
mapIndexed はインデックス付きです。
mapNotNull はラムダ式内の結果がnullだった場合はそれを除外します。

val numberList = listOf(1, 2, 3, 4, 5)
val nullList = listOf(1, null, 3, null)

println(numberList.map { it * 2 })
println(numberList.mapIndexed { idx, value -> idx + value })
println(nullList.mapNotNull { it?.toString() })
出力
[2, 4, 6, 8, 10]
[1, 3, 5, 7, 9]
[1, 3]

maxBy, minBy, maxWith, minWith

ラムダ式で指定した条件で各要素を判定したときの最大・最小の値を返します。
~With は引数に Comparator を取ることで比較方法を指定できる。

val stringList = listOf("a", "bb", "ccc")
val numberList = listOf(1, 2, 3, 4, 5)

println(stringList.maxBy { it.length })
println(stringList.minBy { it.length })
println(numberList.maxWith(Comparator { a, b -> b - a }))
println(numberList.minWith(Comparator { a, b -> b - a }))
出力
ccc
a
1
5

minus

引数で指定した要素を差し引いたlistを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.minus(2))
println(numberList.minus(listOf(1, 3)))
出力
[1, 3, 4, 5]
[2, 4, 5]

none

ラムダ式に指定した条件の要素がなければ true を返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.none { it > 5 })
出力
true

partition

各要素がラムダ式で指定した条件に対してtrueのものとfalseのものに分割したPairを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.partition { it % 2 == 0 })
出力
([2, 4], [1, 3, 5])

plus

引数で指定した要素を追加したlistを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.plus(2))
println(numberList.plus(listOf(1, 3)))
出力
[1, 2, 3, 4, 5, 2]
[1, 2, 3, 4, 5, 1, 3]

random

listからランダムに一つの要素を取り出します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.random())
出力
1

reduce

ラムダ式に指定した処理を重ねて処理をします。
第一引数には最初はlistの最初の要素、以降はラムダ式で処理した直前の値が入ります。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.reduce({ acc, value ->
    print("${acc} * ${value} = ")
    acc * value
}))
出力
1 * 2 = 2 * 3 = 6 * 4 = 24 * 5 = 120

requireNoNulls

listにnullがないか確認し、なければlistを返します。
null がある場合は IllegalArgumentException が発生します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.requireNoNulls())
出力
[1, 2, 3, 4, 5]

reversed

listを逆順にしたlistを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.reversed())
出力
[5, 4, 3, 2, 1]

shuffled

listの各要素をシャッフルしたlistを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.shuffled())
出力
[1, 3, 5, 4, 2]

single, singleOrNull

listに存在する唯一の要素を取得します。
ラムダ式で条件も指定可能です。
該当する要素が存在しない、もしくは複数存在する場合はIllegalArgumentExceptionが発生します。
singleOrNullはエラーの代わりにnullを返します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.single { it == 2 })
println(numberList.singleOrNull())
出力
2
null

slice

引数に指定した範囲でlistを分割します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.slice(1..2))
出力
[2, 3]

sorted, sortedDescending, sortBy, sortedWith

listをソートします。
sortedDescending は降順。
sortBy はソート方法をラムダ式で調整。
sortedWith はソート条件を Comparator で指定。

val sortList = listOf(1, 5, 4, 3, 2)

println(sortList.sorted())
println(sortList.sortedDescending())
println(sortList.sortedBy { it * -1 })
println(sortList.sortedWith(Comparator { a, b -> a - b }))
出力
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
[5, 4, 3, 2, 1]
[1, 2, 3, 4, 5]

subtract

指定したcollectionに存在しない要素だけを抽出してSetで返します。
重複は除去されます。

val numberList = listOf(1, 2, 3, 4, 5)
val subtractList = listOf(2, 3)

println(numberList.subtract(subtractList))
出力
[1, 4, 5]

sum, sumBy

要素の合計を返します。
sumBy はラムダ式で値を変更できます。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.sum())
println(numberList.sumBy { it * 10 })
出力
15
150

take, takeLast, takeWhile

指定した数だけlistから要素を取得します。
takeLast はlistの後ろから取得します。
takeWhile は指定した条件がtrueの間取得します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.take(2))
println(numberList.takeLast(2))
println(numberList.takeWhile { it < 4 })
出力
[1, 2]
[4, 5]
[1, 2, 3]

union

2つのlistの要素を合計してSetを返します。
重複は除去されます。

val numberList = listOf(1, 2, 3, 4, 5)
val unionList = listOf(3, 4, 5, 6, 7)

println(numberList.union(unionList))
出力
[1, 2, 3, 4, 5, 6, 7]

unzip

Pair のlistのkeyだけ、valueだけをまとめたlistのPairを返します。

val pairList = listOf(Pair(1, "one"), Pair(2, "two"), Pair(3, "three"))

println(pairList.unzip())
出力
([1, 2, 3], [one, two, three])

windowed

listを指定したサイズ・間隔で分割したlistにします。
partialWindowstrue の場合はsizeに満たないはみ出した要素も出力します。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.windowed(size = 2, step = 2, partialWindows = true))
println(numberList.windowed(size = 2, step = 2))
出力
[[1, 2], [3, 4], [5]]
[[1, 2], [3, 4]]

withIndex

listをindexつきにします。

val numberList = listOf(1, 2, 3, 4, 5)

numberList.withIndex().forEach { print("${it.index} : ${it.value}, ") }
出力
0 : 1, 1 : 2, 2 : 3, 3 : 4, 4 : 5, 

zip

listどうしの各要素をPairにします。
不足する要素は無視されます。
第二引数にラムダ式を指定することでPair以外に変換できます。

val zip1 = listOf(1, 2, 3, 4)
val zip2 = listOf("one", "two", "three")

println(zip1.zip(zip2))
println(zip1.zip(zip2, { a, b -> "${a} = ${b}" }))
出力
[(1, one), (2, two), (3, three)]
[1 = one, 2 = two, 3 = three]

zipWithNext

listの各要素を、次の要素とのPairにします。
ラムダ式で条件を指定することでPair以外に変換できます。

val numberList = listOf(1, 2, 3, 4, 5)

println(numberList.zipWithNext())
println(numberList.zipWithNext { a, b -> a + b })
出力
[(1, 2), (2, 3), (3, 4), (4, 5)]
[3, 5, 7, 9]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away