Skip to content

循环语句

概述

Kotlin提供了多种循环结构来重复执行代码块,包括for循环、while循环和do-while循环。Kotlin的循环语句功能强大,支持区间、集合遍历、以及各种控制流操作。

for 循环

基本 for 循环

kotlin
fun main() {
    // 遍历区间
    println("基本for循环:")
    for (i in 1..5) {
        println("数字: $i")
    }
    
    // 遍历字符区间
    println("\n字符区间:")
    for (c in 'a'..'e') {
        println("字符: $c")
    }
    
    // 使用until(不包含结束值)
    println("\nuntil循环:")
    for (i in 1 until 5) {
        println("数字: $i")
    }
    
    // 递减循环
    println("\n递减循环:")
    for (i in 5 downTo 1) {
        println("倒数: $i")
    }
    
    // 指定步长
    println("\n指定步长:")
    for (i in 1..10 step 2) {
        println("奇数: $i")
    }
    
    for (i in 10 downTo 1 step 3) {
        println("递减步长3: $i")
    }
}

遍历集合

kotlin
fun main() {
    val fruits = listOf("苹果", "香蕉", "橙子", "葡萄")
    val numbers = arrayOf(1, 2, 3, 4, 5)
    val map = mapOf("a" to 1, "b" to 2, "c" to 3)
    
    // 遍历列表
    println("遍历列表:")
    for (fruit in fruits) {
        println("水果: $fruit")
    }
    
    // 遍历数组
    println("\n遍历数组:")
    for (number in numbers) {
        println("数字: $number")
    }
    
    // 带索引遍历
    println("\n带索引遍历:")
    for ((index, fruit) in fruits.withIndex()) {
        println("$index: $fruit")
    }
    
    // 遍历映射
    println("\n遍历映射:")
    for ((key, value) in map) {
        println("$key -> $value")
    }
    
    // 只遍历键或值
    println("\n只遍历键:")
    for (key in map.keys) {
        println("键: $key")
    }
    
    println("\n只遍历值:")
    for (value in map.values) {
        println("值: $value")
    }
}

嵌套循环

kotlin
fun main() {
    // 打印乘法表
    println("乘法表:")
    for (i in 1..9) {
        for (j in 1..i) {
            print("${j}×${i}=${i*j}\t")
        }
        println()
    }
    
    // 二维数组遍历
    val matrix = arrayOf(
        arrayOf(1, 2, 3),
        arrayOf(4, 5, 6),
        arrayOf(7, 8, 9)
    )
    
    println("\n矩阵遍历:")
    for (row in matrix) {
        for (element in row) {
            print("$element\t")
        }
        println()
    }
    
    // 带索引的二维遍历
    println("\n带索引的矩阵遍历:")
    for ((rowIndex, row) in matrix.withIndex()) {
        for ((colIndex, element) in row.withIndex()) {
            println("matrix[$rowIndex][$colIndex] = $element")
        }
    }
}

while 循环

基本 while 循环

kotlin
fun main() {
    // 基本while循环
    var count = 1
    println("while循环:")
    while (count <= 5) {
        println("计数: $count")
        count++
    }
    
    // 条件复杂的while循环
    var number = 1
    println("\n2的幂次:")
    while (number <= 100) {
        println("2^${kotlin.math.log2(number.toDouble()).toInt()} = $number")
        number *= 2
    }
    
    // 用户输入模拟(实际应用中会从控制台读取)
    val inputs = listOf("hello", "world", "quit", "more")
    var inputIndex = 0
    
    println("\n模拟用户输入:")
    while (inputIndex < inputs.size) {
        val input = inputs[inputIndex]
        println("输入: $input")
        
        if (input == "quit") {
            println("退出程序")
            break
        }
        
        inputIndex++
    }
}

do-while 循环

kotlin
fun main() {
    // do-while循环(至少执行一次)
    var attempts = 0
    val maxAttempts = 3
    
    println("do-while循环示例:")
    do {
        attempts++
        println("尝试第 $attempts 次")
        
        // 模拟某种条件检查
        val success = attempts >= 2  // 第2次尝试成功
        
        if (success) {
            println("操作成功!")
            break
        } else {
            println("操作失败,重试...")
        }
        
    } while (attempts < maxAttempts)
    
    if (attempts >= maxAttempts) {
        println("达到最大尝试次数")
    }
    
    // 菜单系统示例
    val menuOptions = listOf("1. 查看", "2. 添加", "3. 删除", "0. 退出")
    val userChoices = listOf("1", "2", "invalid", "0")  // 模拟用户选择
    var choiceIndex = 0
    
    println("\n菜单系统:")
    do {
        println("\n请选择操作:")
        menuOptions.forEach { println(it) }
        
        val choice = if (choiceIndex < userChoices.size) {
            userChoices[choiceIndex++]
        } else {
            "0"
        }
        
        println("您的选择: $choice")
        
        when (choice) {
            "1" -> println("执行查看操作")
            "2" -> println("执行添加操作")
            "3" -> println("执行删除操作")
            "0" -> println("退出系统")
            else -> println("无效选择,请重新输入")
        }
        
    } while (choice != "0")
}

循环控制语句

break 和 continue

kotlin
fun main() {
    // break示例
    println("break示例 - 找到第一个偶数:")
    for (i in 1..10) {
        if (i % 2 == 0) {
            println("找到第一个偶数: $i")
            break
        }
        println("检查: $i")
    }
    
    // continue示例
    println("\ncontinue示例 - 跳过偶数:")
    for (i in 1..10) {
        if (i % 2 == 0) {
            continue  // 跳过偶数
        }
        println("奇数: $i")
    }
    
    // 在嵌套循环中使用break和continue
    println("\n嵌套循环中的控制:")
    for (i in 1..3) {
        println("外层循环: $i")
        for (j in 1..5) {
            if (j == 3) {
                println("  跳过内层 $j")
                continue
            }
            if (j == 4) {
                println("  内层循环提前结束")
                break
            }
            println("  内层循环: $j")
        }
    }
}

标签和跳转

kotlin
fun main() {
    // 使用标签控制嵌套循环
    println("标签跳转示例:")
    
    outer@ for (i in 1..3) {
        inner@ for (j in 1..3) {
            if (i == 2 && j == 2) {
                println("在 ($i, $j) 处跳出外层循环")
                break@outer  // 跳出外层循环
            }
            println("($i, $j)")
        }
    }
    
    println("\n标签continue示例:")
    outer@ for (i in 1..3) {
        for (j in 1..3) {
            if (j == 2) {
                println("在 ($i, $j) 处继续外层循环")
                continue@outer  // 继续外层循环的下一次迭代
            }
            println("($i, $j)")
        }
    }
}

函数式循环操作

forEach 和其他高阶函数

kotlin
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    // forEach
    println("forEach:")
    numbers.forEach { number ->
        println("数字: $number")
    }
    
    // forEachIndexed
    println("\nforEachIndexed:")
    numbers.forEachIndexed { index, number ->
        println("索引 $index: $number")
    }
    
    // map - 转换每个元素
    println("\nmap - 平方:")
    val squares = numbers.map { it * it }
    println(squares)
    
    // filter - 过滤元素
    println("\nfilter - 偶数:")
    val evens = numbers.filter { it % 2 == 0 }
    println(evens)
    
    // 链式操作
    println("\n链式操作 - 偶数的平方:")
    val evenSquares = numbers
        .filter { it % 2 == 0 }
        .map { it * it }
    println(evenSquares)
    
    // reduce - 聚合操作
    println("\nreduce - 求和:")
    val sum = numbers.reduce { acc, number -> acc + number }
    println("总和: $sum")
    
    // fold - 带初始值的聚合
    println("\nfold - 带初始值求积:")
    val product = numbers.fold(1) { acc, number -> acc * number }
    println("乘积: $product")
}

repeat 函数

kotlin
fun main() {
    // repeat函数
    println("repeat函数:")
    repeat(5) { index ->
        println("重复 $index 次")
    }
    
    // 实际应用:重试机制
    fun simulateNetworkCall(): Boolean {
        return kotlin.random.Random.nextBoolean()
    }
    
    println("\n重试机制示例:")
    var success = false
    repeat(3) { attempt ->
        println("尝试第 ${attempt + 1} 次网络请求")
        success = simulateNetworkCall()
        if (success) {
            println("请求成功!")
            return@repeat  // 提前退出repeat
        } else {
            println("请求失败")
        }
    }
    
    if (!success) {
        println("所有重试都失败了")
    }
}

实际应用示例

数据处理

kotlin
data class Student(val name: String, val age: Int, val grades: List<Int>)

fun main() {
    val students = listOf(
        Student("Alice", 20, listOf(85, 92, 78, 96)),
        Student("Bob", 19, listOf(76, 84, 88, 79)),
        Student("Charlie", 21, listOf(95, 89, 92, 98)),
        Student("Diana", 20, listOf(82, 87, 85, 90))
    )
    
    println("学生成绩分析:")
    
    // 计算每个学生的平均成绩
    for (student in students) {
        val average = student.grades.average()
        val grade = when {
            average >= 90 -> "A"
            average >= 80 -> "B"
            average >= 70 -> "C"
            else -> "D"
        }
        println("${student.name} (${student.age}岁): 平均分 %.1f, 等级 $grade".format(average))
    }
    
    // 找出最高分学生
    var topStudent: Student? = null
    var highestAverage = 0.0
    
    for (student in students) {
        val average = student.grades.average()
        if (average > highestAverage) {
            highestAverage = average
            topStudent = student
        }
    }
    
    println("\n最高分学生: ${topStudent?.name}, 平均分: %.1f".format(highestAverage))
    
    // 统计各等级人数
    val gradeCount = mutableMapOf("A" to 0, "B" to 0, "C" to 0, "D" to 0)
    
    for (student in students) {
        val average = student.grades.average()
        val grade = when {
            average >= 90 -> "A"
            average >= 80 -> "B"
            average >= 70 -> "C"
            else -> "D"
        }
        gradeCount[grade] = gradeCount[grade]!! + 1
    }
    
    println("\n等级统计:")
    for ((grade, count) in gradeCount) {
        println("等级 $grade: $count 人")
    }
}

游戏开发示例

kotlin
class GameBoard(val size: Int) {
    private val board = Array(size) { Array(size) { '.' } }
    
    fun placeSymbol(row: Int, col: Int, symbol: Char): Boolean {
        return if (isValidPosition(row, col) && board[row][col] == '.') {
            board[row][col] = symbol
            true
        } else {
            false
        }
    }
    
    private fun isValidPosition(row: Int, col: Int): Boolean {
        return row in 0 until size && col in 0 until size
    }
    
    fun display() {
        println("  " + (0 until size).joinToString(" "))
        for ((rowIndex, row) in board.withIndex()) {
            print("$rowIndex ")
            for (cell in row) {
                print("$cell ")
            }
            println()
        }
    }
    
    fun checkWin(symbol: Char): Boolean {
        // 检查行
        for (row in board) {
            var count = 0
            for (cell in row) {
                if (cell == symbol) count++ else count = 0
                if (count >= 3) return true
            }
        }
        
        // 检查列
        for (col in 0 until size) {
            var count = 0
            for (row in 0 until size) {
                if (board[row][col] == symbol) count++ else count = 0
                if (count >= 3) return true
            }
        }
        
        // 检查对角线
        for (startRow in 0 until size - 2) {
            for (startCol in 0 until size - 2) {
                var count = 0
                for (i in 0 until 3) {
                    if (board[startRow + i][startCol + i] == symbol) {
                        count++
                    } else {
                        break
                    }
                }
                if (count >= 3) return true
            }
        }
        
        return false
    }
}

fun main() {
    val game = GameBoard(5)
    val moves = listOf(
        Triple(0, 0, 'X'), Triple(0, 1, 'O'),
        Triple(1, 1, 'X'), Triple(1, 2, 'O'),
        Triple(2, 2, 'X'), Triple(2, 3, 'O')
    )
    
    println("井字游戏演示:")
    game.display()
    
    for ((row, col, symbol) in moves) {
        println("\n玩家 $symbol 在 ($row, $col) 下棋")
        if (game.placeSymbol(row, col, symbol)) {
            game.display()
            if (game.checkWin(symbol)) {
                println("玩家 $symbol 获胜!")
                break
            }
        } else {
            println("无效移动!")
        }
    }
}

算法实现

kotlin
// 冒泡排序
fun bubbleSort(arr: IntArray) {
    val n = arr.size
    for (i in 0 until n - 1) {
        var swapped = false
        for (j in 0 until n - i - 1) {
            if (arr[j] > arr[j + 1]) {
                // 交换元素
                val temp = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = temp
                swapped = true
            }
        }
        // 如果没有交换,说明已经排序完成
        if (!swapped) break
    }
}

// 二分查找
fun binarySearch(arr: IntArray, target: Int): Int {
    var left = 0
    var right = arr.size - 1
    
    while (left <= right) {
        val mid = left + (right - left) / 2
        
        when {
            arr[mid] == target -> return mid
            arr[mid] < target -> left = mid + 1
            else -> right = mid - 1
        }
    }
    
    return -1  // 未找到
}

// 斐波那契数列
fun fibonacci(n: Int): Long {
    if (n <= 1) return n.toLong()
    
    var prev = 0L
    var curr = 1L
    
    for (i in 2..n) {
        val next = prev + curr
        prev = curr
        curr = next
    }
    
    return curr
}

fun main() {
    // 排序演示
    val numbers = intArrayOf(64, 34, 25, 12, 22, 11, 90)
    println("排序前: ${numbers.contentToString()}")
    bubbleSort(numbers)
    println("排序后: ${numbers.contentToString()}")
    
    // 二分查找演示
    val target = 25
    val index = binarySearch(numbers, target)
    if (index != -1) {
        println("找到 $target 在索引 $index")
    } else {
        println("未找到 $target")
    }
    
    // 斐波那契数列
    println("\n斐波那契数列前10项:")
    for (i in 0..9) {
        print("${fibonacci(i)} ")
    }
    println()
}

性能优化

循环优化技巧

kotlin
fun main() {
    val largeList = (1..1000000).toList()
    
    // 1. 使用适当的循环类型
    // 对于简单遍历,forEach通常比传统for循环快
    
    // 2. 避免在循环中创建不必要的对象
    // 不好的做法
    fun badExample() {
        for (i in largeList) {
            val result = "Number: $i"  // 每次都创建新字符串
            // 处理result...
        }
    }
    
    // 好的做法
    fun goodExample() {
        val sb = StringBuilder()
        for (i in largeList) {
            sb.clear()
            sb.append("Number: ").append(i)
            val result = sb.toString()
            // 处理result...
        }
    }
    
    // 3. 使用序列进行延迟计算
    val result = largeList.asSequence()
        .filter { it % 2 == 0 }
        .map { it * it }
        .take(10)
        .toList()
    
    println("前10个偶数的平方: $result")
    
    // 4. 提前退出循环
    fun findFirst(predicate: (Int) -> Boolean): Int? {
        for (item in largeList) {
            if (predicate(item)) {
                return item  // 找到后立即返回
            }
        }
        return null
    }
    
    val firstLargeNumber = findFirst { it > 500000 }
    println("第一个大于500000的数: $firstLargeNumber")
}

最佳实践

1. 选择合适的循环类型

kotlin
fun main() {
    val items = listOf("a", "b", "c", "d", "e")
    
    // 简单遍历:使用forEach
    items.forEach { println(it) }
    
    // 需要索引:使用forEachIndexed或withIndex
    items.forEachIndexed { index, item ->
        println("$index: $item")
    }
    
    // 需要转换:使用map
    val upperCase = items.map { it.uppercase() }
    
    // 需要过滤:使用filter
    val filtered = items.filter { it != "c" }
    
    // 复杂逻辑:使用传统for循环
    for (i in items.indices) {
        if (i > 0 && items[i] == items[i-1]) {
            // 复杂的相邻元素比较逻辑
        }
    }
}

2. 避免嵌套过深

kotlin
// 不好的做法:嵌套过深
fun badNestedLoops(matrix: Array<Array<Int>>) {
    for (i in matrix.indices) {
        for (j in matrix[i].indices) {
            for (k in 0..10) {
                if (matrix[i][j] == k) {
                    for (l in 0..5) {
                        // 嵌套太深,难以理解
                    }
                }
            }
        }
    }
}

// 好的做法:提取函数
fun goodNestedLoops(matrix: Array<Array<Int>>) {
    for (i in matrix.indices) {
        for (j in matrix[i].indices) {
            processCell(matrix[i][j])
        }
    }
}

fun processCell(value: Int) {
    for (k in 0..10) {
        if (value == k) {
            performOperation(k)
        }
    }
}

fun performOperation(k: Int) {
    for (l in 0..5) {
        // 具体操作
    }
}

下一步

掌握了循环语句后,让我们学习Kotlin中的函数定义和使用,包括高阶函数、lambda表达式等。

下一章: 函数

练习题

  1. 编写一个程序来生成指定大小的乘法表
  2. 实现一个简单的猜数字游戏,使用循环处理用户输入
  3. 创建一个函数来计算数组中所有元素的统计信息(最大值、最小值、平均值等)
  4. 实现选择排序算法,并比较其与冒泡排序的性能
  5. 编写一个程序来生成帕斯卡三角形的前n行

本站内容仅供学习和研究使用。