Kotlinの forEach は、コレクションや配列などの要素を1つずつ取り出して、順番に処理するための関数です。
たとえば、リストの中身を順番に表示したいときに使えます。
val fruits = listOf("apple", "banana", "orange")
fruits.forEach {
println(it)
}
このコードでは、apple → banana → orange の順に表示されます。
基本構文
collection.forEach { element ->
処理
}
引数が1つだけなら、名前を省略して it が使えます。
val numbers = listOf(1, 2, 3)
numbers.forEach {
println(it)
}
これは次と同じ意味です。
numbers.forEach { number ->
println(number)
}
it と明示的な名前の使い分け
短い処理なら it で十分ですが、意味が分かりにくくなるなら名前を付けたほうが読みやすいです。
users.forEach { user ->
println(user.name)
}
forEach が使える主な対象
forEach は代表的に次のようなものに使えます。
List
val names = listOf("Taro", "Hanako", "Jiro")
names.forEach {
println(it)
}
Set
val numbers = setOf(10, 20, 30)
numbers.forEach {
println(it)
}
ただし、Set は重複しない要素の集合であり、List のような「順序付きコレクション」とは性質が異なります。
実装によっては見かけ上順番どおりに見えることもありますが、概念としては順序を前提にしないほうが安全です。
配列
val arr = arrayOf("A", "B", "C")
arr.forEach {
println(it)
}
Map
Map の場合は、各要素が Map.Entry として扱われます。
val scores = mapOf("Alice" to 80, "Bob" to 90)
scores.forEach {
println("${it.key}: ${it.value}")
}
分解代入で書くこともできます。
scores.forEach { (name, score) ->
println("$name: $score")
}
forEachIndexed との違い
forEach は要素そのものを順番に処理します。
一方で、インデックスも必要な場合は forEachIndexed を使います。
val fruits = listOf("apple", "banana", "orange")
fruits.forEachIndexed { index, fruit ->
println("$index: $fruit")
}
出力
0: apple
1: banana
2: orange
使い分け
- 要素だけ必要 →
forEach - 添字も必要 →
forEachIndexed
forEach と for 文の違い
forEach も for 文も、どちらも繰り返し処理に使えます。
for 文
for (fruit in fruits) {
println(fruit)
}
forEach
fruits.forEach {
println(it)
}
forEach の特徴
- 短く書きやすい
- Kotlinらしい書き方になる
mapやfilterなどの関数型スタイルと相性がよい
for 文の特徴
breakやcontinueをそのまま使える- 複雑な分岐や途中終了が分かりやすい
- 制御構文として直感的
つまり、単純に各要素へ同じ処理をしたいなら forEach、途中終了や複雑な制御が必要なら for 文 が向いています。
forEach と break / continue
ここはとても重要です。
forEach のラムダの中では、for 文のように break や continue をそのまま書けません。
なぜなら、forEach はループ構文そのものではなく、関数にラムダを渡している形だからです。
continue に近いことをしたい場合
たとえば、奇数をスキップして偶数だけ表示したいとします。
for 文なら
for (n in listOf(1, 2, 3, 4, 5)) {
if (n % 2 != 0) continue
println(n)
}
forEach なら
listOf(1, 2, 3, 4, 5).forEach {
if (it % 2 != 0) return@forEach
println(it)
}
return@forEach は、その回のラムダ処理だけを終えて、次の要素へ進む動きです。
これは continue に近い挙動 です。
break に近いことをしたい場合
たとえば、3 が出たらそこで処理全体を止めたい場合です。
for 文なら自然
for (n in listOf(1, 2, 3, 4, 5)) {
if (n == 3) break
println(n)
}
forEach ではどうか
forEach には、break に対応する直接的な書き方はありません。
そのため、途中終了したい処理では、普通の for 文を使うほうが自然で分かりやすいです。
return の挙動に注意
Kotlin の forEach では、return の意味が少し特殊になることがあります。
特に、関数の中で forEach を使うときは注意が必要です。
fun printNumbers() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return
println(it)
}
println("終了")
}
この場合、it == 3 になったとき、forEach だけでなく printNumbers() 自体が終了します。
出力
1
2
終了 は表示されません。
なぜそうなるのか
これは、forEach が inline 関数 だからです。
Kotlin では、inline 関数に渡したラムダの中でラベルなしの return を使うと、外側の関数から戻ることがあります。
このような戻り方を、non-local return と呼びます。
forEach だけ抜けたいわけではない場合
「forEach の今の1回だけを終えて、次へ進みたい」なら return@forEach を使います。
fun printNumbers() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach
println(it)
}
println("終了")
}
出力
1
2
4
5
終了
ここでの return@forEach は、その要素の処理だけを終えるものです。
ラベル付きで書く方法
forEach には独自ラベルを付けることもできます。
fun sample() {
listOf(1, 2, 3, 4, 5).forEach myLabel@{
if (it == 3) return@myLabel
println(it)
}
println("done")
}
これは return@forEach と似た意味です。
ただし、通常は return@forEach のほうが分かりやすいので、まずはこちらを使えば十分です。
forEach は値を返さない
forEach は各要素に対して処理を実行するための関数であり、変換結果のリストを返す関数ではありません。
val numbers = listOf(1, 2, 3)
val result = numbers.forEach {
println(it)
}
この result の型は Unit です。
つまり forEach は、
- 表示する
- ログを出す
- 保存する
- 集計用の変数を更新する
といった、副作用を伴う処理に向いています。
変換したいなら map
forEach と map はよく混同されますが、役割はまったく違います。
forEach
各要素に対して処理を実行するだけ
val numbers = listOf(1, 2, 3)
numbers.forEach {
println(it * 2)
}
map
変換結果を新しいリストとして返す
val numbers = listOf(1, 2, 3)
val doubled = numbers.map {
it * 2
}
println(doubled)
出力
[2, 4, 6]
判断基準
- 何かを表示したい、保存したい、処理したい →
forEach - 新しいコレクションを作りたい →
map
forEach のよくある使い方
1つずつ表示する
val items = listOf("pen", "notebook", "eraser")
items.forEach {
println(it)
}
条件付きで処理する
val numbers = listOf(1, 2, 3, 4, 5)
numbers.forEach {
if (it % 2 == 0) {
println("偶数: $it")
}
}
オブジェクトのプロパティを使う
data class User(val name: String, val age: Int)
val users = listOf(
User("Alice", 20),
User("Bob", 25)
)
users.forEach { user ->
println("${user.name} is ${user.age} years old")
}
集計に使う例
val numbers = listOf(10, 20, 30)
var sum = 0
numbers.forEach {
sum += it
}
println(sum)
この書き方は正しいですが、集計が目的なら sum() や fold() のような専用関数のほうが意図が明確な場合もあります。
forEach を使わないほうがよい場面
次のようなケースでは、無理に forEach を使うより for 文のほうが読みやすいことがあります。
途中で打ち切りたい
for (item in items) {
if (item == target) break
}
複雑な条件分岐がある
for (item in items) {
if (condition1) {
println("A")
} else if (condition2) {
println("B")
} else {
println("C")
}
}
ループ制御を細かく書きたい
この場合も、制御構文である for 文のほうが意図が伝わりやすいです。
初心者がハマりやすいポイント
forEach は新しいリストを返さない
val result = listOf(1, 2, 3).forEach {
it * 2
}
この result は変換後のリストにはなりません。
forEach の戻り値は Unit です。
変換したいなら map を使います。
ラベルなし return で外側の関数が終わることがある
fun test() {
listOf(1, 2, 3).forEach {
if (it == 2) return
println(it)
}
println("end")
}
この場合、2 に来た時点で test() 全体が終了します。
break の代わりには向いていない
forEach には break に相当する直接的な書き方がありません。
途中終了したい処理では for 文のほうが素直です。
実務での使い分け
forEach が向いている場面
- 各要素に同じ処理を順にしたい
- 表示、ログ出力、保存などの副作用が中心
- 短くシンプルに書きたい
for 文が向いている場面
breakを使いたいcontinueを分かりやすく書きたい- ループ制御が複雑
- 可読性を優先したい
まとめ
Kotlin の forEach は、コレクションや配列などの各要素に対して順番に処理を実行する関数です。
覚えておくべきポイントを整理すると、次の通りです。
forEachは各要素を順番に処理する- 引数が1つなら
itが使える - インデックスも必要なら
forEachIndexed forEachはUnitを返す- 新しいコレクションを作りたいなら
map - ラムダ内で
break/continueはそのまま使えない return@forEachはcontinueに近い動きbreakに対応する直接的な書き方はないので、途中終了したいならfor文が自然- ラベルなし
returnは、外側の関数から戻ることがある
最後にシンプル比較
forEach
listOf(1, 2, 3).forEach {
println(it)
}
forEachIndexed
listOf("a", "b", "c").forEachIndexed { index, value ->
println("$index: $value")
}
map
val result = listOf(1, 2, 3).map {
it * 2
}
println(result)
for
for (n in listOf(1, 2, 3)) {
if (n == 2) break
println(n)
}
以上、KotlinのforEachについてでした。
最後までお読みいただき、ありがとうございました。










