Kotlin 遍历

在 Kotlin 中,遍历(迭代)是操作集合、数组、范围(Range)等数据结构的常见需求。Kotlin 提供了多种遍历方式,语法简洁且功能强大。以下是不同场景下的遍历方法总结,附代码示例:

一、遍历集合(List/Set)

Kotlin 的 ListSet 是最常用的集合类型,遍历方式包括传统 for 循环、forEach 高阶函数、forEachIndexed(带索引)等。

1. 基础 for 循环(直接遍历元素)

Kotlin 的 for 循环可直接遍历集合的元素(无需通过索引),语法简洁:

复制代码
val fruits = listOf("Apple", "Banana", "Cherry", "Date")

// 遍历所有元素
for (fruit in fruits) {
    println(fruit) // 输出:Apple, Banana, Cherry, Date
}
2. forEach 高阶函数(函数式风格)

通过集合的扩展函数 forEach,可以更函数式地遍历元素。适用于需要对每个元素执行操作的场景:

复制代码
fruits.forEach { fruit ->
    println(fruit) // 输出同上
}

// 简化写法(使用 it 代替参数名)
fruits.forEach { println(it) }
3. forEachIndexed(带索引遍历)

若需要同时获取元素的索引 ,可以使用 forEachIndexed

复制代码
fruits.forEachIndexed { index, fruit ->
    println("索引 $index: $fruit") 
    // 输出:索引 0: Apple,索引 1: Banana,...
}
4. 通过索引遍历(传统方式)

通过 indices 获取集合的索引范围(0..size-1),再通过索引访问元素:

复制代码
for (index in fruits.indices) {
    val fruit = fruits[index]
    println("索引 $index: $fruit") // 输出同上
}

二、遍历 Map(键值对)

Map 存储键值对(Key-Value),遍历需同时处理键和值。Kotlin 提供了多种遍历方式:

1. 遍历 entries(键值对)

通过 map.entries 获取所有键值对(类型为 Set<Map.Entry<K, V>>),直接遍历每个 Entry

复制代码
val userMap = mapOf(
    "name" to "Alice",
    "age" to 25,
    "city" to "Beijing"
)

// 遍历键值对(Entry)
for ((key, value) in userMap) {
    println("$key: $value") 
    // 输出:name: Alice,age: 25,city: Beijing
}

// 或使用 forEach
userMap.forEach { (key, value) ->
    println("$key: $value")
}
2. 单独遍历键(Keys)或值(Values)

通过 map.keys 遍历所有键,或通过 map.values 遍历所有值:

复制代码
// 遍历所有键
for (key in userMap.keys) {
    println("Key: $key") // 输出:name,age,city
}

// 遍历所有值
userMap.values.forEach { value ->
    println("Value: $value") // 输出:Alice,25,Beijing
}

三、遍历数组(Array)

Kotlin 的数组(如 IntArrayStringArray)与集合的遍历方式类似,但需注意基本类型数组(如 IntArray)的优化。

1. 对象数组(Array<T>

普通对象数组的遍历方式与集合完全一致:

复制代码
val stringArray = arrayOf("A", "B", "C")

// for 循环
for (str in stringArray) {
    println(str)
}

// forEach
stringArray.forEach { println(it) }
2. 基本类型数组(如 IntArray

Kotlin 对基本类型数组(IntArrayBooleanArray 等)做了优化,避免装箱开销。遍历方式与对象数组类似:

复制代码
val intArray = intArrayOf(1, 2, 3, 4)

// for 循环
for (num in intArray) {
    println(num) // 输出:1, 2, 3, 4
}

// forEach(优化版,无装箱)
intArray.forEach { println(it) }

// 带索引遍历
intArray.forEachIndexed { index, num ->
    println("索引 $index: $num")
}

四、遍历范围(Range)

Kotlin 的范围(如 1..10 表示闭区间 [1,10])支持高效遍历,常用于循环计数。

1. 整数范围(IntRange

通过 .. 操作符创建范围,配合 for 循环遍历:

复制代码
// 遍历 1 到 5(包含 5)
for (i in 1..5) {
    println(i) // 输出:1, 2, 3, 4, 5
}

// 倒序遍历(使用 downTo)
for (i in 5 downTo 1) {
    println(i) // 输出:5, 4, 3, 2, 1
}

// 带步长遍历(使用 step)
for (i in 1..5 step 2) {
    println(i) // 输出:1, 3, 5
}
2. 字符范围(CharRange

字符也可以组成范围,按 ASCII 顺序遍历:

复制代码
// 遍历 A 到 C
for (c in 'A'..'C') {
    println(c) // 输出:A, B, C
}

五、遍历迭代器(Iterator)

若需要手动控制遍历过程(如跳过某些元素),可以通过 iterator() 获取迭代器,然后使用 hasNext()next() 遍历:

复制代码
val numbers = listOf(10, 20, 30, 40)
val iterator = numbers.iterator()

while (iterator.hasNext()) {
    val num = iterator.next()
    println(num) // 输出:10, 20, 30, 40
}

六、注意事项

  1. breakcontinue 的限制

    • 在传统 for 循环中可以使用 break(终止循环)和 continue(跳过当前迭代);
    • forEach 高阶函数中不支持 breakcontinue(因为本质是函数调用)。若需要提前终止,需改用 for 循环或使用 takeWhile 等操作符。

    示例:提前终止遍历

    复制代码
    // 使用 for 循环 + break(推荐)
    for (fruit in fruits) {
        if (fruit == "Cherry") break // 遇到 "Cherry" 时终止循环
        println(fruit) // 输出:Apple, Banana
    }
    
    // 使用 takeWhile(函数式风格,返回满足条件的子列表)
    fruits.takeWhile { it != "Cherry" }.forEach { println(it) }
  2. 不可变集合 vs 可变集合

    若遍历的是可变集合(如 MutableList),在遍历过程中修改集合 (添加 / 删除元素)可能导致 ConcurrentModificationException(并发修改异常)。需使用 listIterator 或复制集合后遍历。

总结:按场景选择遍历方式

场景 推荐方法 示例代码
简单遍历集合元素 for 循环 或 forEach for (item in list)list.forEach { ... }
需要索引和元素 forEachIndexed list.forEachIndexed { index, item -> ... }
遍历 Map 键值对 for ((key, value) in map) for ((k, v) in map) { ... }
遍历范围(如 1 到 10) for (i in 1..10) for (i in start..end) { ... }
需要提前终止或跳过元素 传统 for 循环 + break/continue for (item in list) { if (...) break }

通过灵活选择这些遍历方式,可以高效处理 Kotlin 中各种数据结构的遍历需求。

相关推荐
studyer_domi1 分钟前
Matlab 分数阶PID控制
开发语言·matlab
液态不合群2 分钟前
rust程序静态编译的两种方法总结
开发语言·后端·rust
人间有清欢6 分钟前
Android开发补充内容
android·okhttp·rxjava·retrofit·hilt·jetpack compose
学地理的小胖砸42 分钟前
【Python 日期和时间】
开发语言·python
想成为大佬的每一天44 分钟前
Linux网络编程day7 线程池and UDP
linux·开发语言
人间有清欢1 小时前
Android开发报错解决
android
waterHBO1 小时前
python 上海新闻爬虫
开发语言·爬虫·python
CHANG_THE_WORLD1 小时前
Mac 平台获取地区标识符号
java·开发语言·macos
cykaw25901 小时前
QT QList容器及行高亮
开发语言·qt
人类群星闪耀时1 小时前
R语言数据挖掘:从“挖井”到“淘金”
开发语言·数据挖掘·r语言