Kotlinのfor文について

採用はこちら

Kotlinのfor文は、リスト・配列・文字列・範囲などを順番に処理するときに使います。

JavaのようなC言語風の for (初期化; 条件; 更新) ではなく、Kotlinではin を使って対象を順に反復するのが基本です。

基本形はこれです。

for (変数 in 対象) {
    処理
}

たとえば、リストの要素を順番に表示するならこう書きます。

val fruits = listOf("Apple", "Banana", "Orange")

for (fruit in fruits) {
    println(fruit)
}

出力

Apple
Banana
Orange
目次

Kotlinのfor文の基本

Kotlinのfor文は、反復できる対象を順番に処理する構文です。

たとえば次のように使います。

val numbers = listOf(10, 20, 30)

for (number in numbers) {
    println(number)
}

この場合、numbers の中の要素が1つずつ number に入り、順番に処理されます。

数値の範囲を使うfor文

Kotlinでは、数値の範囲を使って繰り返すこともよくあります。

.. は終端を含む

for (i in 1..5) {
    println(i)
}

出力

1
2
3
4
5

1..5 は、1から5までを意味します。

ポイントは、最後の5も含まれることです。

until は終端を含まない

for (i in 1 until 5) {
    println(i)
}

出力

1
2
3
4

1 until 5 は、1以上5未満です。

つまり、最後の 5 は含みません。

..< も終端を含まない

最近のKotlinでは、until と同じく終端を含まない範囲として ..< も使えます。

for (i in 1..<5) {
    println(i)
}

出力:

1
2
3
4

1 until 51..<5 は、基本的に同じ結果になります。

downTo で逆順にする

大きい数から小さい数へ処理したいときは downTo を使います。

for (i in 5 downTo 1) {
    println(i)
}

出力

5
4
3
2
1

step で間隔を指定する

for (i in 1..10 step 2) {
    println(i)
}

出力

1
3
5
7
9

2ずつ増やして処理しています。

逆順でも使えます。

for (i in 10 downTo 1 step 2) {
    println(i)
}

出力

10
8
6
4
2

リストや配列に対するfor文

要素をそのまま処理する

もっとも基本的で読みやすい書き方です。

val names = listOf("Taro", "Hanako", "Jiro")

for (name in names) {
    println(name)
}

インデックスが必要ないなら、この書き方を優先するのが自然です。

インデックスを使うなら indices

val names = listOf("Taro", "Hanako", "Jiro")

for (i in names.indices) {
    println("$i: ${names[i]}")
}

出力

0: Taro
1: Hanako
2: Jiro

indices は、そのコレクションで有効なインデックス範囲を返します。

インデックスと要素を同時に使うなら withIndex()

val names = listOf("Taro", "Hanako", "Jiro")

for ((index, name) in names.withIndex()) {
    println("$index: $name")
}

この書き方はKotlinらしく、読みやすいです。

0 until size も使える

val items = listOf("A", "B", "C")

for (i in 0 until items.size) {
    println(items[i])
}

これも正しい書き方です。

ただし、Kotlinでは indiceswithIndex() のほうが意図が伝わりやすい場面も多いです。

文字列に対するfor文

Kotlinでは、文字列も1文字ずつ処理できます。

val text = "Kotlin"

for (ch in text) {
    println(ch)
}

出力

K
o
t
l
i
n

文字単位の処理をしたいときに便利です。

break と continue

break はループを終了する

for (i in 1..10) {
    if (i == 5) {
        break
    }
    println(i)
}

出力

1
2
3
4

i == 5 になった時点で、ループ全体を終了します。

continue はその回だけスキップする

for (i in 1..5) {
    if (i == 3) {
        continue
    }
    println(i)
}

出力

1
2
4
5

3 のときだけ処理を飛ばして、次の繰り返しへ進みます。

ネストしたfor文

for文の中に for文を書くこともできます。

for (i in 1..3) {
    for (j in 1..2) {
        println("i=$i, j=$j")
    }
}

出力

i=1, j=1
i=1, j=2
i=2, j=1
i=2, j=2
i=3, j=1
i=3, j=2

表形式の処理や2次元データの処理でよく使います。

ラベル付きbreak / continue

ネストしたループでは、どのループに対して breakcontinue を使うかを明示したいことがあります。

そのときにラベルを使います。

outer@ for (i in 1..3) {
    for (j in 1..3) {
        if (i == 2 && j == 2) {
            break@outer
        }
        println("i=$i, j=$j")
    }
}

この場合、条件を満たしたときに内側だけでなく外側のループごと終了します。

continue@outer と書けば、外側ループの次の回へ進めます。

Javaのfor文との違い

Javaでは、次のようなCスタイルのfor文がよく使われます。

for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

Kotlinではこの形式は使えません。

代わりに、次のように書きます。

for (i in 0 until 5) {
    println(i)
}

つまりKotlinでは、初期化・条件・更新を書くのではなく、反復する対象を in で指定するのが基本です。

for文とforEachの違い

Kotlinでは forEach もよく使われます。

val fruits = listOf("Apple", "Banana", "Orange")

fruits.forEach {
    println(it)
}

ただし、forEachfor文そのものではなく、各要素に処理を適用する関数です。

そのため使い分けはこう考えるとわかりやすいです。

for が向いている場面

  • breakcontinue を使いたい
  • インデックス制御を明確にしたい
  • 通常のループとして読みやすく書きたい

forEach が向いている場面

  • 短く書きたい
  • 各要素に同じ処理をするだけで十分
  • 関数型っぽく書きたい

初心者のうちは、まず for 文をしっかり理解するのがおすすめです。

よくあるミス

..until を混同する

次のコードは危険です。

val list = listOf("A", "B", "C")

for (i in 0..list.size) {
    println(list[i])
}

.. は終端を含むので、list.size まで到達してしまいます。

しかし、インデックスとして有効なのは 0 から list.size - 1 までです。

そのため最後に範囲外アクセスになります。

正しくは次のように書きます。

for (i in 0 until list.size) {
    println(list[i])
}

または、より自然に書くならこうです。

for (item in list) {
    println(item)
}

あるいはインデックスが必要ならこうです。

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

インデックスが不要なのに無理に使う

val names = listOf("A", "B", "C")

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

これは間違いではありません。

ただ、インデックスが不要なら次のほうがシンプルです。

for (name in names) {
    println(name)
}

Kotlinでは、必要のないインデックス操作は避けたほうが読みやすくなりやすいです。

while文との違い

for文は、反復する対象や範囲が決まっているときに向いています。

for (i in 1..5) {
    println(i)
}

一方、while文は、条件が真である間だけ繰り返したいときに向いています。

var i = 1
while (i <= 5) {
    println(i)
    i++
}

使い分けの目安

  • コレクションや範囲を順番に処理する → for
  • 条件によって繰り返し回数が変わる → while

Kotlinのfor文を理解するコツ

Kotlinのfor文では、Javaのように「変数を初期化して、条件判定して、毎回更新する」という考え方よりも、「この対象を順番に反復する」という発想のほうが大切です。

たとえば、

for (i in 1..5) {
    println(i)
}

は、「iを自分で増やしている」のではなく、1..5 という範囲を順番に処理していると考えると理解しやすくなります。

よく使うパターン一覧

// 1から5まで(5を含む)
for (i in 1..5) { }

// 1から4まで(5を含まない)
for (i in 1 until 5) { }

// 1から4まで(5を含まない)
for (i in 1..<5) { }

// 5から1まで
for (i in 5 downTo 1) { }

// 2ずつ増やす
for (i in 0..10 step 2) { }

// リストの要素を順に処理
for (item in items) { }

// インデックスを使う
for (i in items.indices) { }

// インデックスと要素を同時に使う
for ((index, item) in items.withIndex()) { }

// 文字列を1文字ずつ処理
for (ch in text) { }

最後に覚えるべき重要ポイント

Kotlinのfor文では、まず次の点を押さえると理解しやすいです。

  1. 基本形は for (x in 対象)
  2. 数値の繰り返しでは ..until..<downTostep を使う
  3. リスト処理では、まず for (item in list) を考える
  4. インデックスが必要なら indiceswithIndex() を使う
  5. .. は終端を含むので、インデックス処理では注意する
  6. breakcontinue が必要なら for が扱いやすい

練習用のサンプル

1から10まで表示する

for (i in 1..10) {
    println(i)
}

10から1まで逆順に表示する

for (i in 10 downTo 1) {
    println(i)
}

リストの要素を表示する

val animals = listOf("Dog", "Cat", "Bird")

for (animal in animals) {
    println(animal)
}

インデックスと要素を同時に表示する

val animals = listOf("Dog", "Cat", "Bird")

for ((index, animal) in animals.withIndex()) {
    println("$index: $animal")
}

以上、Kotlinのfor文についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次