HoRain云--Kotlin循环控制完全指南
🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录
⛳️ 推荐
Kotlin 循环控制完全指南
📊 循环控制概览
🎯 一、基础循环结构
1.1 for 循环
1.2 while 和 do-while
1.3 repeat 函数
🔧 二、循环控制语句
2.1 break 和 continue
2.2 标签和返回控制
🎨 三、函数式循环操作
3.1 集合高阶函数
3.2 惰性求值与序列
🔄 四、高级循环模式
4.1 自定义迭代器
4.2 协程中的循环
🎯 五、性能优化与最佳实践
5.1 性能优化技巧
5.2 最佳实践指南
📈 六、实战案例
6.1 数据分析流水线
6.2 游戏循环模拟
🎯 总结要点
Kotlin 循环控制完全指南
Kotlin 提供了丰富灵活的循环控制机制,融合了传统的命令式循环和现代的函数式编程特性。
📊 循环控制概览
循环类型 | 语法 | 适用场景 | 特点 |
|---|---|---|---|
for |
| 遍历集合、范围 | 简洁、类型推断 |
while |
| 条件循环 | 前置条件检查 |
do-while |
| 至少执行一次 | 后置条件检查 |
repeat |
| 固定次数循环 | 替代传统 for-i |
forEach |
| 函数式遍历 | lambda 表达式 |
高阶函数 |
| 数据转换 | 函数式组合 |
🎯 一、基础循环结构
1.1 for 循环
fun main() { // 1. 范围遍历 (range) println("=== 范围遍历 ===") for (i in 1..5) { // 1到5包含5 print("$i ") // 1 2 3 4 5 } println() for (i in 1 until 5) { // 1到5不包含5 print("$i ") // 1 2 3 4 } println() for (i in 5 downTo 1) { // 递减 print("$i ") // 5 4 3 2 1 } println() for (i in 1..10 step 2) { // 步长 print("$i ") // 1 3 5 7 9 } println("\n") // 2. 集合遍历 println("=== 集合遍历 ===") val fruits = listOf("Apple", "Banana", "Orange", "Grape") // 遍历元素 for (fruit in fruits) { print("$fruit ") // Apple Banana Orange Grape } println() // 带索引遍历 for ((index, fruit) in fruits.withIndex()) { println("$index: $fruit") // 0: Apple, 1: Banana... } // 3. 数组遍历 val numbers = arrayOf(10, 20, 30, 40, 50) for (num in numbers) { print("$num ") // 10 20 30 40 50 } println("\n") // 4. 字符串遍历 val text = "Kotlin" for (char in text) { print("$char ") // K o t l i n } println() // 5. 带步长的字符范围 for (char in 'a'..'z' step 2) { print("$char ") // a c e g i k m o q s u w y } println() }1.2 while 和 do-while
fun main() { // 1. while 循环 println("=== while 循环 ===") var count = 5 while (count > 0) { print("$count ") // 5 4 3 2 1 count-- } println() // 2. do-while 循环 (至少执行一次) println("=== do-while 循环 ===") var number: Int do { print("请输入正数: ") number = readlnOrNull()?.toIntOrNull() ?: -1 } while (number <= 0) println("你输入的是: $number") // 3. 模拟猜数字游戏 println("=== 猜数字游戏 ===") val secretNumber = (1..100).random() var guess: Int var attempts = 0 do { print("猜一个1-100之间的数: ") guess = readlnOrNull()?.toIntOrNull() ?: 0 attempts++ when { guess < secretNumber -> println("太小了!") guess > secretNumber -> println("太大了!") else -> println("🎉 恭喜!你用了 $attempts 次猜对了") } } while (guess != secretNumber) // 4. 输入验证循环 println("=== 输入验证 ===") var validInput = false var userAge: Int = 0 while (!validInput) { print("请输入年龄 (1-120): ") val input = readlnOrNull() if (input != null) { userAge = input.toIntOrNull() ?: 0 if (userAge in 1..120) { validInput = true } else { println("无效的年龄,请重新输入") } } } println("年龄验证通过: $userAge") }1.3 repeat 函数
fun main() { // 1. 基本使用 println("=== repeat 函数 ===") repeat(5) { index -> print("$index ") // 0 1 2 3 4 } println() // 2. 替代传统 for-i 循环 repeat(3) { iteration -> println("执行第 ${iteration + 1} 次") } // 3. 打印星形图案 repeat(5) { row -> repeat(row + 1) { print("*") } println() } // * // ** // *** // **** // ***** // 4. 带间隔的重复 fun printSeparator() = println("----------") repeat(4) { println("任务 ${it + 1}") printSeparator() } // 5. 计时重复 val startTime = System.currentTimeMillis() repeat(1_000_000) { // 模拟工作 val x = it * it } val duration = System.currentTimeMillis() - startTime println("执行100万次耗时: ${duration}ms") }🔧 二、循环控制语句
2.1 break 和 continue
fun main() { // 1. break - 提前终止循环 println("=== break 语句 ===") for (i in 1..10) { if (i == 6) { println("遇到6,终止循环") break } print("$i ") // 1 2 3 4 5 } println() // 2. continue - 跳过当前迭代 println("=== continue 语句 ===") for (i in 1..10) { if (i % 2 == 0) { continue // 跳过偶数 } print("$i ") // 1 3 5 7 9 } println() // 3. 多层循环中的 break println("=== 多层循环 break ===") outer@ for (i in 1..3) { inner@ for (j in 1..3) { if (i == 2 && j == 2) { println("跳出外层循环") break@outer } println("i=$i, j=$j") } } // i=1, j=1 // i=1, j=2 // i=1, j=3 // i=2, j=1 // 跳出外层循环 // 4. 多层循环中的 continue println("=== 多层循环 continue ===") for (i in 1..3) { for (j in 1..3) { if (j == 2) { continue // 跳过内层循环的 j=2 } println("i=$i, j=$j") } } // i=1, j=1 // i=1, j=3 // i=2, j=1 // i=2, j=3 // i=3, j=1 // i=3, j=3 // 5. 寻找质数 println("=== 寻找质数 ===") val numbers = listOf(23, 29, 31, 37, 41, 43, 47, 49, 53) for (num in numbers) { if (num < 2) continue // 跳过小于2的数 var isPrime = true for (i in 2 until num) { if (num % i == 0) { isPrime = false break // 发现因子,立即退出内层循环 } } if (isPrime) { print("$num ") // 23 29 31 37 41 43 47 53 } } println() }2.2 标签和返回控制
fun main() { // 1. 带标签的 break println("=== 带标签的 break ===") loop@ for (i in 1..3) { for (j in 1..3) { if (i * j > 4) { println("i=$i, j=$j 乘积大于4,跳出外层") break@loop } println("i=$i, j=$j -> ${i * j}") } } // 2. 带标签的 continue println("=== 带标签的 continue ===") outer@ for (i in 1..3) { for (j in 1..3) { if (j == 2) { continue@outer // 跳过当前外层迭代的剩余部分 } println("i=$i, j=$j") } } // 3. lambda 中的返回控制 println("=== lambda 返回控制 ===") val numbers = listOf(1, 2, 3, 4, 5) // 局部返回 (返回到 lambda 的调用者) numbers.forEach { if (it == 3) return@forEach // 相当于 continue print("$it ") // 1 2 4 5 } println() // 4. 命名函数的返回 fun findFirstEven(nums: List<Int>): Int? { nums.forEach { if (it % 2 == 0) { return it // 从整个函数返回 } } return null } val result = findFirstEven(listOf(1, 3, 5, 2, 4, 6)) println("第一个偶数是: $result") // 2 // 5. 模拟异常情况处理 println("=== 模拟异常处理 ===") val data = listOf("10", "20", "abc", "40", "50") try { data.forEach loop@{ str -> val num = str.toIntOrNull() if (num == null) { println("遇到无效数字 '$str',跳过后续处理") return@loop // 跳过当前项 } println("处理数字: $num") } } catch (e: Exception) { println("发生异常: ${e.message}") } }🎨 三、函数式循环操作
3.1 集合高阶函数
fun main() { val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val names = listOf("Alice", "Bob", "Charlie", "David", "Eve") // 1. forEach - 遍历元素 println("=== forEach ===") numbers.forEach { print("$it ") } // 1 2 3 4 5 6 7 8 9 10 println() names.forEachIndexed { index, name -> println("$index: $name") } // 2. filter - 筛选元素 println("=== filter ===") val evens = numbers.filter { it % 2 == 0 } println("偶数: $evens") // [2, 4, 6, 8, 10] val longNames = names.filter { it.length > 4 } println("长名字: $longNames") // [Alice, Charlie, David] // 3. map - 转换元素 println("=== map ===") val squares = numbers.map { it * it } println("平方: $squares") // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] val upperNames = names.map { it.uppercase() } println("大写: $upperNames") // [ALICE, BOB, CHARLIE, DAVID, EVE] // 4. fold/reduce - 累积操作 println("=== fold/reduce ===") val sum = numbers.reduce { acc, num -> acc + num } println("总和: $sum") // 55 val product = numbers.fold(1) { acc, num -> acc * num } println("乘积: $product") // 3628800 val concatenated = names.fold("") { acc, name -> if (acc.isEmpty()) name else "$acc, $name" } println("连接: $concatenated") // Alice, Bob, Charlie, David, Eve // 5. take/drop - 切片操作 println("=== take/drop ===") val firstThree = numbers.take(3) val lastTwo = numbers.takeLast(2) val withoutFirstTwo = numbers.drop(2) println("前3个: $firstThree") // [1, 2, 3] println("后2个: $lastTwo") // [9, 10] println("去掉前2个: $withoutFirstTwo") // [3, 4, 5, 6, 7, 8, 9, 10] // 6. 链式操作 println("=== 链式操作 ===") val result = numbers .filter { it % 2 == 1 } // 奇数 [1, 3, 5, 7, 9] .map { it * 2 } // 翻倍 [2, 6, 10, 14, 18] .take(3) // 取前3个 [2, 6, 10] .fold(0) { acc, num -> acc + num } println("链式结果: $result") // 18 }3.2 惰性求值与序列
fun main() { // 1. 序列 vs 集合 println("=== 序列 vs 集合 ===") val bigCollection = (1..1_000_000).toList() // 集合操作 - 立即求值 val start1 = System.currentTimeMillis() val result1 = bigCollection .filter { it % 2 == 0 } .map { it * 2 } .take(10) val time1 = System.currentTimeMillis() - start1 println("集合操作时间: ${time1}ms, 结果: $result1") // 序列操作 - 惰性求值 val start2 = System.currentTimeMillis() val result2 = bigCollection.asSequence() .filter { it % 2 == 0 } .map { it * 2 } .take(10) .toList() val time2 = System.currentTimeMillis() - start2 println("序列操作时间: ${time2}ms, 结果: $result2") // 2. 序列操作符 println("=== 序列操作符 ===") val sequence = generateSequence(1) { it + 1 } // 无限序列 val limitedSeq = sequence .filter { it % 3 == 0 } .map { "数字-$it" } .take(5) println("有限序列: ${limitedSeq.toList()}") // [数字-3, 数字-6, 数字-9, 数字-12, 数字-15] // 3. 生成斐波那契序列 println("=== 斐波那契序列 ===") val fibonacci = sequence { var a = 0 var b = 1 yield(a) yield(b) while (true) { val next = a + b yield(next) a = b b = next } } val fib10 = fibonacci.take(10).toList() println("前10个斐波那契数: $fib10") // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] // 4. windowed - 滑动窗口 println("=== 滑动窗口 ===") val data = listOf(10, 20, 30, 40, 50, 60) val windows = data.windowed(size = 3, step = 1) println("滑动窗口: $windows") // [[10, 20, 30], [20, 30, 40], [30, 40, 50], [40, 50, 60]] // 5. zip - 配对操作 println("=== zip 操作 ===") val letters = listOf("A", "B", "C", "D") val scores = listOf(95, 88, 92, 78) val paired = letters.zip(scores) { letter, score -> "$letter: $score" } println("配对结果: $paired") // [A: 95, B: 88, C: 92, D: 78] // 6. chunked - 分批处理 println("=== 分批处理 ===") val largeList = (1..20).toList() val chunks = largeList.chunked(5) println("分批结果: $chunks") // [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], ...] }🔄 四、高级循环模式
4.1 自定义迭代器
// 1. 自定义集合类 class NumberRange(private val start: Int, private val end: Int) : Iterable<Int> { override fun iterator(): Iterator<Int> = NumberIterator(start, end) inner class NumberIterator(private val start: Int, private val end: Int) : Iterator<Int> { private var current = start override fun hasNext(): Boolean = current <= end override fun next(): Int { if (!hasNext()) throw NoSuchElementException() return current++ } } } // 2. 自定义步长迭代器 class SteppedRange( private val start: Int, private val end: Int, private val step: Int ) : Iterable<Int> { init { require(step > 0) { "步长必须为正数" } } override fun iterator(): Iterator<Int> = SteppedIterator(start, end, step) inner class SteppedIterator( private val start: Int, private val end: Int, private val step: Int ) : Iterator<Int> { private var current = start override fun hasNext(): Boolean = current <= end override fun next(): Int { if (!hasNext()) throw NoSuchElementException() val result = current current += step return result } } } // 3. 反向迭代器 class ReversibleList<T>(private val list: List<T>) : Iterable<T> { override fun iterator(): Iterator<T> = ReverseIterator(list) inner class ReverseIterator<T>(private val list: List<T>) : Iterator<T> { private var index = list.size - 1 override fun hasNext(): Boolean = index >= 0 override fun next(): T { if (!hasNext()) throw NoSuchElementException() return list[index--] } } } // 4. 使用示例 fun main() { println("=== 自定义迭代器 ===") // 自定义范围 val range = NumberRange(5, 10) for (num in range) { print("$num ") // 5 6 7 8 9 10 } println() // 带步长的范围 val stepped = SteppedRange(0, 10, 2) for (num in stepped) { print("$num ") // 0 2 4 6 8 10 } println() // 反向列表 val names = listOf("Alice", "Bob", "Charlie", "David") val reversed = ReversibleList(names) for (name in reversed) { print("$name ") // David Charlie Bob Alice } println() // 5. 生成器函数 fun generatePrimes(limit: Int): Sequence<Int> = sequence { var num = 2 while (num <= limit) { if (isPrime(num)) { yield(num) } num++ } } val primes = generatePrimes(50).toList() println("50以内的质数: $primes") } fun isPrime(n: Int): Boolean { if (n < 2) return false for (i in 2 until n) { if (n % i == 0) return false } return true }4.2 协程中的循环
import kotlinx.coroutines.* suspend fun main() { // 1. 协程中的异步循环 println("=== 协程循环 ===") coroutineScope { // 并发执行多个任务 val jobs = listOf("任务A", "任务B", "任务C", "任务D") jobs.forEach { jobName -> launch { delay((1000L..3000L).random()) // 模拟工作时间 println("$jobName 完成 - ${Thread.currentThread().name}") } } } // 2. 流式处理 println("=== 流式处理 ===") flow { for (i in 1..5) { delay(500L) emit("数据-$i") } }.collect { value -> println("收到: $value") } // 3. 超时循环 println("=== 超时循环 ===") try { withTimeout(2500L) { repeat(10) { i -> println("执行 $i") delay(1000L) } } } catch (e: TimeoutCancellationException) { println("操作超时: ${e.message}") } }🎯 五、性能优化与最佳实践
5.1 性能优化技巧
fun main() { // 1. 集合 vs 序列性能对比 val largeList = (1..1_000_000).toList() // ❌ 不佳做法:中间集合创建 val slowResult = largeList .filter { it % 2 == 0 } // 创建中间集合 .map { it * 2 } // 创建中间集合 .take(1000) // 最终结果 // ✅ 优化做法:使用序列 val fastResult = largeList.asSequence() .filter { it % 2 == 0 } // 惰性操作 .map { it * 2 } // 惰性操作 .take(1000) // 及早终止 .toList() // 2. 避免不必要的迭代 val users = listOf("Alice", "Bob", "Charlie") // ❌ 不佳做法:多次遍历 val hasAdmin = users.any { it == "Admin" } val adminCount = users.count { it == "Admin" } // 再次遍历 // ✅ 优化做法:单次遍历 var adminCountOptimal = 0 var hasAdminOptimal = false users.forEach { user -> if (user == "Admin") { adminCountOptimal++ hasAdminOptimal = true } } // 3. 及早终止优化 val numbers = generateSequence(1) { it + 1 } // 找到第一个满足条件的元素后就停止 val firstMatch = numbers .filter { println("过滤 $it") it % 321 == 0 } .find { println("检查 $it") it > 9000 } println("找到的结果: $firstMatch") // 4. 缓存中间结果 data class Expensive(val value: Int) { init { Thread.sleep(10) // 模拟昂贵计算 } } val sourceList = (1..1000).toList() // ❌ 不佳做法:重复计算 val expensiveObjs1 = sourceList.map { Expensive(it) } val filtered1 = expensiveObjs1.filter { it.value % 2 == 0 } val transformed1 = expensiveObjs1.map { it.value * 3 } // ✅ 优化做法:缓存计算结果 val cachedExpensive = sourceList.map { Expensive(it) } val filtered2 = cachedExpensive.filter { it.value % 2 == 0 } val transformed2 = cachedExpensive.map { it.value * 3 } // 5. 并行处理(使用协程) suspend fun processBatch(data: List<Int>): List<String> = coroutineScope { data.map { item -> async { // 模拟异步处理 delay((100L..500L).random()) "处理结果-$item" } }.awaitAll() } }5.2 最佳实践指南
fun main() { // 1. 优先使用高阶函数 val transactions = listOf(100, -50, 75, -20, 125, -35) // ✅ 推荐:使用标准库函数 val positiveSum = transactions .filter { it > 0 } .sum() val negativeCount = transactions.count { it < 0 } // 2. 使用范围表达式代替传统for-i // ✅ 推荐 for (i in 0 until 10) { ... } for (i in 10 downTo 0 step 2) { ... } // 3. 善用结构化控制 data class User(val name: String, val active: Boolean) val users = listOf( User("Alice", true), User("Bob", false), User("Charlie", true) ) // ✅ 清晰的意图表达 users.filter { it.active } .sortedBy { it.name } .forEach { println("活跃用户: ${it.name}") } // 4. 错误处理模式 val riskyData = listOf("10", "20", "invalid", "40") // ✅ 安全的空值处理 val safeValues = riskyData.mapNotNull { it.toIntOrNull() } println("有效数值: $safeValues") // [10, 20, 40] // 5. 使用序列处理大数据集 fun processLargeData(): List<Result> { return generateLargeDataset() .asSequence() // 转为序列 .filter { isValid(it) } // 惰性过滤 .map { transform(it) } // 惰性转换 .takeWhile { shouldContinue(it) } // 条件终止 .toList() // 最终物化 } // 6. 领域特定循环模式 class SensorDataProcessor { fun monitorContinuous(readings: Sequence<Double>) { readings.windowed(10, 1) { window -> val avg = window.average() if (avg > THRESHOLD) { triggerAlert(avg) } } } companion object { const val THRESHOLD = 80.0 } } // 7. 测试友好循环 interface DataSource { fun fetchData(): List<String> } class MockDataSource : DataSource { override fun fetchData(): List<String> = listOf("test1", "test2") } fun processData(source: DataSource) { source.fetchData().forEach { item -> // 可测试的业务逻辑 } } }📈 六、实战案例
6.1 数据分析流水线
data class Sale(val product: String, val amount: Double, val region: String, val date: String) fun main() { val sales = listOf( Sale("Laptop", 899.99, "US", "2024-01-15"), Sale("Phone", 499.99, "EU", "2024-01-15"), Sale("Tablet", 399.99, "US", "2024-02-05"), Sale("Laptop", 799.99, "CN", "2024-03-10"), Sale("Phone", 549.99, "US", "2024-06-08"), Sale("Watch", 249.99, "JP", "2024-07-19") ) // 1. 销售分析流水线 val analysis = sales .filter { it.region == "US" } // 筛选美国地区 .groupBy { it.product } // 按产品分组 .mapValues { (_, sales) -> sales.sumOf { it.amount } // 计算各产品销售额 } .entries .sortedByDescending { it.value } // 按销售额降序 println("=== 美国地区销售排名 ===") analysis.forEach { (product, revenue) -> println("${product}: $${revenue}") } // 2. 月度趋势分析 val monthlyTrend = sales .groupBy { it.date.substringBefore('-', "") } // 按月分组 .mapValues { (month, monthSales) -> mapOf( "total" to monthSales.sumOf { it.amount }, "count" to monthSales.size, "avg" to monthSales.sumOf { it.amount } / monthSales.size ) } println("\n=== 月度销售趋势 ===") monthlyTrend.forEach { (month, stats) -> println("$month月: 总额=${stats["total"]}, 订单=${stats["count"]}, 均价=${stats["avg"]}") } // 3. 产品区域分布 val productDistribution = sales .groupBy { it.product } .mapValues { (_, productSales) -> productSales.groupBy { it.region } .mapValues { (_, sales) -> sales.size } } println("\n=== 产品区域分布 ===") productDistribution.forEach { (product, dist) -> println("$product: $dist") } }6.2 游戏循环模拟
import kotlin.random.Random class GameEngine { private var running = false private var frameCount = 0 fun startGame() { running = true frameCount = 0 gameLoop@ while (running) { frameCount++ // 1. 处理输入 val input = simulateInput() // 2. 更新游戏状态 val gameOver = updateGameState(input) // 3. 渲染画面 renderFrame() // 4. 帧率控制 (模拟) Thread.sleep(16) // ~60 FPS // 5. 游戏结束检查 if (gameOver || frameCount >= 3600) { // 1分钟游戏时间 println("游戏结束!总分: ${calculateScore()}") break@gameLoop } } } private fun simulateInput(): String { return when (Random.nextInt(100)) { in 0..70 -> "move" in 71..85 -> "attack" in 86..94 -> "skill" else -> "quit" } } private fun updateGameState(action: String): Boolean { // 模拟游戏逻辑更新 return when (action) { "quit" -> { println("玩家退出游戏") true } else -> { // 继续游戏 if (frameCount % 240 == 0) { // 每4秒 println("游戏进行中... 帧数: $frameCount") } false } } } private fun renderFrame() { // 模拟渲染操作 if (frameCount % 480 == 0) { // 每8秒 println("渲染复杂场景...") } } private fun calculateScore(): Int { return frameCount * Random.nextInt(10, 101) } fun stopGame() { running = false } } fun main() { val engine = GameEngine() println("=== 游戏循环演示 ===") engine.startGame() }🎯 总结要点
优先函数式风格 - 使用
filter/map/fold替代手动循环善用序列优化 - 大数据集处理使用
asSequence()避免中间集合及早终止原则 - 使用
find/takeWhile避免不必要的迭代安全控制 - 配合空安全特性编写健壮循环
协程整合 - 异步场景结合协程实现高效并发
适度抽象 - 复杂逻辑封装为可复用的迭代器和序列
Kotlin 的循环控制既保留了传统结构的直观性,又提供了现代化函数式编程的强大能力,是编写高效、安全代码的关键工具。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
