Kotlinでループ処理をマスターする方法12選 – Japanシーモア

Kotlinでループ処理をマスターする方法12選

Kotlin言語のロゴとループのシンボルが重なったデザインKotlin
この記事は約16分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読めば、Kotlinでのループ処理を完璧にマスターすることができるようになります。

ループ処理はプログラミングにおいて必須の技能であり、効率的なコードを書くためには、その理解と正しい使い方を知っていることが不可欠です。

今回はKotlinでのループ処理の基本から応用、さらには注意点やカスタマイズ方法まで、12の具体的な方法をサンプルコードと共に解説します。

プログラミングの世界に足を踏み入れたばかりの方も、これからKotlinを学びたいと考えている方も、この記事を最後まで読むことで、ループ処理に自信を持って取り組むことができるでしょう。

●Kotlinでのループ処理とは

Kotlinでのループ処理は、特定の操作を繰り返し実行するためのプログラミング技法です。

これにより、コードの冗長性を減らし、効率的なプログラミングが可能になります。

例えば、1000件のデータを1件ずつ処理する際、1000行のコードを書く必要がなく、ループ処理を利用して数行のコードで完結させることができます。

○ループ処理の基本概念

ループ処理は、指定された条件が真である間、特定のコードブロックを繰り返し実行するものです。

Kotlinにおいては、主にfor文、while文、do-while文などが利用されます。

それぞれ特徴と適用シーンが異なるため、具体的なケースに応じて最適なループ処理を選ぶスキルが求められます。

for文は、コレクションや範囲にわたって繰り返し操作を行う際に用います。

while文とdo-while文は、特定の条件が満たされている間、コードブロックを繰り返し実行するために使用されます。

while文は条件を先に評価し、条件が真であればコードブロックを実行します。

do-while文は、コードブロックを先に実行した後、条件を評価し、真であれば再度コードブロックを実行します。

●Kotlinのループ文の種類

Kotlinでは、さまざまなループ文を利用することで、コードの効率化や構造化を実現できます。

これらのループ文を理解し、適切に使用することで、プログラムの動作を柔軟に制御することが可能です。

それでは、主要なループ文とその特徴、使用方法について解説します。

○for文の基本

Kotlinのfor文は、特定の範囲やコレクションに対しての繰り返し処理を行う際に使用します。

基本的な構文は次のようになります。

for (変数 in 範囲やコレクション) {
    // 繰り返し実行する処理
}

このコードでは、指定した範囲やコレクションの要素数分だけ繰り返し処理を行います。

例えば、1から5までの数字を順に表示するプログラムは次のようになります。

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

このコードを実行すると、1から5までの数字が順に表示されます。

○while文とdo-while文の違い

while文とdo-while文は、指定した条件が真(true)の間、繰り返し処理を行います。

これら二つの文の主な違いは、条件の評価タイミングです。

  • while文:条件を先に評価し、条件が真の場合に繰り返し処理を行います。
  • do-while文:まず一度処理を実行し、その後で条件を評価します。条件が真であれば、再度処理を繰り返します。

while文の基本的な構文は次の通りです。

while (条件) {
    // 繰り返し実行する処理
}

一方、do-while文の構文は次のようになります。

do {
    // 繰り返し実行する処理
} while (条件)

例えば、変数countが5になるまでの間、countの値を表示するプログラムは次のように書けます。

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

このコードを実行すると、1から5までの数字が順に表示されます。

●Kotlinのループ処理の使い方

Kotlinでのループ処理は、繰り返しの処理を実現するための強力な手段です。

効率的なコーディングを目指す際に、ループ処理の使い方をマスターすることは欠かせません。

ここでは、いくつかの代表的なループ処理の使い方をサンプルコードとともにご紹介します。

○サンプルコード1:基本的なfor文を使ってリストを処理する

Kotlinでは、リストや配列の各要素に対して処理を繰り返す際、for文が頻繁に利用されます。

例として、整数のリストの各要素を順番に表示するシンプルな例を紹介します。

val numbers = listOf(1, 2, 3, 4, 5)
for (num in numbers) {
    // リストの各要素を出力
    println(num)
}

このコードを実行することで、1から5までの数字が順番に画面に表示されることになります。

○サンプルコード2:範囲を指定したfor文の使い方

Kotlinでは、特定の範囲を指定してfor文を使うことができます。

for (i in 1..10) {
    // 指定範囲内の数字を出力
    println(i)
}

このコードでは1から10までの数字が順番に出力されます。

範囲を指定する際、..を利用することで、開始値と終了値を簡潔に示すことができます。

○サンプルコード3:while文での条件ループ処理

Kotlinのwhile文は、指定した条件が真(true)の間、ブロック内のコードを繰り返し実行します。

例として、1から5までの数字を順に表示するサンプルコードを紹介します。

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

このコードでは、countという変数を1で初期化し、while文の中でcountが5以下である限り数字を出力して、その後でcountを1増やします。

したがって、1から5までの数字が順に表示される結果となります。

○サンプルコード4:do-while文でのループ処理

do-while文は、while文と非常に似ていますが、一つ大きな違いがあります。

do-while文は、ブロック内のコードを最初に一度実行した後、指定した条件を評価します。

条件が真(true)の場合、再度コードを実行します。

下記のサンプルコードは、0から4までの数字を順に表示するものです。

var number = 0
do {
    println(number)
    number++
} while (number < 5)

このコードを実行すると、0から4までの数字が順番に表示されます。

do-while文の特徴として、条件が初めから偽(false)であっても、ブロック内のコードは最低一度は実行される点を理解しておくことが重要です。

●Kotlinでのループ処理の応用例

Kotlinでのループ処理は、単純な数値の繰り返しから、リストやマップのデータ処理まで、多岐にわたる用途で利用されます。

ここでは、Kotlinでのループ処理のさまざまな応用例をいくつか紹介します。

○サンプルコード5:二重ループを使用した行列の処理

二重ループは、ループの中でさらに別のループを実行する方法です。

例として、5×5の行列のすべての要素を表示するサンプルコードを紹介します。

for (i in 1..5) {
    for (j in 1..5) {
        print("$i$j ")
    }
    println()
}

このコードでは、外側のfor文が行を制御し、内側のfor文が列を制御しています。

したがって、1から5までの数字を組み合わせて5×5の行列が表示される結果となります。

○サンプルコード6:ループと関数を組み合わせたリストのフィルタリング

Kotlinでは、ループを利用してリストから特定の条件に合致する要素だけを抽出することができます。

リストから偶数だけを抽出するサンプルコードを紹介します。

val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evenNumbers = mutableListOf<Int>()

for (num in numbers) {
    if (num % 2 == 0) {
        evenNumbers.add(num)
    }
}

println(evenNumbers)

このコードでは、初めに1から10までの数字が含まれるリストを用意し、次に空のmutableListOfをevenNumbersとして宣言しています。

そして、for文を使ってリストの各要素をチェックし、偶数だけをevenNumbersに追加します。

最終的には、偶数だけが含まれるリストが出力される結果となります。

○サンプルコード7:breakとcontinueを用いたループ制御

Kotlinのループ処理では、特定の条件に合致したときにループを中断したり、次の繰り返しに移行するための機能が提供されています。

それがbreakcontinueです。

これらのキーワードを適切に使うことで、より効率的で柔軟なループ処理を実現することができます。

例えば、ある数のリストから最初に見つかった5以上の数字を探し、見つけたらその数字を表示してループを終了する場合、次のようにコードを書くことができます。

val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

for (num in numbers) {
    if (num >= 5) {
        println("最初に見つかった5以上の数字は:$num")
        break
    }
}

このコードでは、リストの数字を順番に確認し、5以上の数字が見つかったときに、その数字を表示してbreakでループを終了しています。

一方、特定の条件を満たす要素に対してのみ処理をスキップして、その次の繰り返しに進める場合にはcontinueを利用します。

下記のコードは、偶数のときだけ処理をスキップし、奇数のときにのみ数字を表示する例を表しています。

for (num in numbers) {
    if (num % 2 == 0) {
        continue
    }
    println("奇数:$num")
}

上記のコードは、数字が偶数の場合にcontinueを実行して、それ以降の処理をスキップしています。

その結果、奇数だけが表示されます。

○サンプルコード8:ラベルを使用したループの脱出

Kotlinでは、複数のネストされたループがある場合に、外側のループまで一気に脱出するためのラベルを使用することができます。

これは特に二重ループや三重ループなど、深いネストが存在する場合に非常に役立ちます。

下記のサンプルコードは、5×5の行列からある条件に合致する要素を探し、見つけた場合にすべてのループを終了する例を表しています。

loop@ for (i in 1..5) {
    for (j in 1..5) {
        if (i * j == 12) {
            println("条件に合致する要素を見つけました:($i, $j)")
            break@loop
        }
    }
}

このコードでは、外側のループにloop@というラベルを付け、内側のループで条件に合致した場合にbreak@loopを実行しています。

これにより、ラベルがついている最も外側のループまで一気に脱出することができます。

●注意点と対処法

Kotlinでのループ処理を行う際に、特に初心者が陥りやすいトラブルや注意すべきポイントがいくつか存在します。

ここでは、これらのポイントに焦点を当て、適切な対処法やヒントを提供していきます。

○無限ループの回避方法

ループ処理の最中に、何らかの条件が満たされることなくずっと同じ処理が繰り返されてしまう現象を「無限ループ」と呼びます。

このような状態になると、プログラムは終了しなくなり、システムリソースを無駄に消費してしまいます。

下記のwhile文のサンプルコードは、無限ループを引き起こす一例です。

var counter = 0
while (counter < 5) {
    println("Counter value: $counter")
    // counterの値がインクリメントされていないため、このループは終了しない。
}

このコードの問題点は、counterの値がループ内で増加していないため、条件counter < 5が常に真である点にあります。

これを避けるためには、ループ内でcounterをインクリメントする必要があります。

修正後のサンプルコードは次の通りです。

var counter = 0
while (counter < 5) {
    println("Counter value: $counter")
    counter++ // ここでcounterの値を増加させる
}

このコードを実行すると、”Counter value: 0″から”Counter value: 4″までのメッセージが順に表示され、ループが正常に終了します。

○ループ内での変数の扱いに注意

ループ内で変数を使用する際には、変数のスコープや値の更新に注意が必要です。

特にfor文の中で変数を定義する場合、その変数はfor文のブロック内でのみ有効となります。

下記のサンプルコードは、for文の中で変数tempを使用し、ループの後でもその変数を参照しようとする例を表しています。

for (i in 1..5) {
    val temp = i * 2
    println("Double of $i: $temp")
}
// println(temp)  // この行はエラーとなる

上記のコードでは、tempはfor文のブロック内でのみ有効であり、ループの外でtempを参照することはできません。

●Kotlinのループ処理のカスタマイズ方法

Kotlinは柔軟性が高く、ループ処理をカスタマイズするための多くの方法が用意されています。

これにより、様々なシチュエーションに合わせて最適なループ処理を実装することが可能です。

ここでは、特定の条件を持つイテレータの作成や、ラムダ式との組み合わせなど、Kotlinでのループ処理をさらに強化するためのテクニックをいくつか紹介します。

○サンプルコード9:独自のイテレータを使用したループ処理

Kotlinでは、自分自身でイテレータを定義することができます。

これにより、特定の条件を持つ要素のみを取り出すなど、カスタマイズされたループ処理を行うことができます。

例えば、偶数のみを返す独自のイテレータを定義したサンプルコードを見てみましょう。

class EvenIterator(val limit: Int) : Iterator<Int> {
    private var current = 0

    override fun hasNext(): Boolean {
        return current <= limit
    }

    override fun next(): Int {
        current += 2
        return current
    }
}

val evenNumbers = EvenIterator(10)
while (evenNumbers.hasNext()) {
    println(evenNumbers.next())
}

このコードでは、EvenIteratorクラスを使用して、2から始まる偶数を10まで取得しています。

このコードを実行すると、2, 4, 6, 8, 10という5つの偶数が順番に表示されます。

○サンプルコード10:ラムダ式とループを組み合わせた処理

Kotlinでは、ラムダ式とループを組み合わせることで、リストやマップなどのコレクションを効率的に処理することができます。

下記のサンプルコードは、リスト内の要素を2倍にして新しいリストを作成する例を表しています。

val numbers = listOf(1, 2, 3, 4, 5)
val doubledNumbers = numbers.map { it * 2 }
println(doubledNumbers) // 結果: [2, 4, 6, 8, 10]

このコードでは、map関数とラムダ式を組み合わせて、numbersリスト内の各要素を2倍にした新しいリストdoubledNumbersを作成しています。

○サンプルコード11:シーケンスを使用した遅延評価のループ

Kotlinのシーケンスは、遅延評価が可能なデータ構造で、特に大量のデータを扱う際や連続した操作を行う場面でのパフォーマンス向上に役立ちます。

シーケンスを使用することで、データの処理が必要になるまで実際の計算が遅れ、不要な中間データの生成を避けることができます。

それでは、リストをシーケンスに変換し、その後のフィルタリングとマッピング操作を遅延評価する例を見てみましょう。

val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val result = numbers.asSequence()
    .filter { it % 2 == 0 }
    .map { it * 2 }
    .toList()

println(result) // 結果: [4, 8, 12, 16, 20]

このコードでは、asSequenceメソッドを用いてリストをシーケンスに変換し、その後、偶数のみを取り出し、それを2倍にしています。

最後にtoListメソッドでシーケンスを再びリストに変換しています。

このとき、filtermapの処理は、toListが呼ばれるまで実際には実行されません。

○サンプルコード12:コレクションの拡張関数を利用したループ処理のカスタマイズ

Kotlinには、コレクションを操作するための多数の拡張関数が用意されています。

これを活用することで、様々なループ処理を簡潔に実装することができます。

下記のサンプルコードは、リスト内の要素を特定の条件でグルーピングする例を表しています。

val words = listOf("apple", "banana", "cherry", "date", "elderberry")

val groupedWords = words.groupBy { it.first() }

println(groupedWords)
// 結果: {a=[apple], b=[banana], c=[cherry], d=[date], e=[elderberry]}

このコードでは、groupBy関数を使用して、各単語の最初の文字をキーとして単語をグルーピングしています。

実行結果として、最初の文字をキーとしたマップが生成されます。

まとめ

Kotlinでのループ処理は非常に多様で、効率的なプログラムを書くためのさまざまなツールが提供されています。

基本的なfor文やwhile文から、リストやシーケンスに対する高度な操作まで、幅広い選択肢があります。

特に、シーケンスやコレクションの拡張関数を活用することで、遅延評価を行ったり、簡潔にデータ操作を行ったりすることができます。

この記事では、Kotlinでのループ処理の基礎から応用、注意点、カスタマイズ方法までを網羅的に解説しました。

これらの知識を組み合わせることで、さまざまなシチュエーションでのデータ処理が可能となります。

Kotlinを使っての開発を進める際、この知識があなたの開発を効率的に、そして楽しくサポートすることを願っています。