1. 概述

数组是存储和操作元素集合的基础数据结构。正向遍历数组是常见操作,但在某些场景下,我们需要反向遍历——从最后一个元素开始,逐个向前访问。

本文将系统介绍在 Kotlin 中实现数组反向遍历的多种方法,适合有一定 Kotlin 使用经验的开发者参考。✅

2. 问题引入

Kotlin 提供了简洁的语法和丰富的内置函数来处理数组。例如,我们可以通过 for 循环或 forEach { } 轻松完成正向遍历:

val array = arrayOf("a", "b", "c", "d", "e", "f")

如果要反向遍历,期望的访问顺序是:"f" -> "e" -> "d" -> "c" -> "b" -> "a"

为验证结果正确性,我们先定义一个预期结果列表:

val reversedList = listOf("f", "e", "d", "c", "b", "a")

接下来,我们逐一探讨实现反向遍历的几种方式。

3. 调用数组的 reversed() 函数

Kotlin 为数组提供了 reversed() 扩展函数,它会返回一个元素顺序颠倒的新列表(注意返回类型是 List<T>,不是 Array<T>):

public fun <T> Array<out T>.reversed(): List<T> { ... }

我们可以结合 for 循环使用:

val resultList = mutableListOf<String>()
for (element in array.reversed()) {
    resultList += element
}
assertEquals(reversedList, resultList)

优点:代码最简洁,语义清晰。
⚠️ 注意reversed() 会创建新列表,对大数组可能有性能开销。如果你只关心遍历过程而不需修改原数组,这是最推荐的方式。

4. 对数组索引范围调用 reversed()

如果需要在遍历过程中使用索引(比如同时访问元素和其位置),可以考虑操作索引本身。

Kotlin 数组有一个 indices 属性,返回一个包含所有有效索引的 IntRange(如 0..5)。而 IntRange 也支持 reversed()

val resultList = mutableListOf<String>()

for (i in array.indices.reversed()) {
    resultList += array[i]
}

assertEquals(reversedList, resultList)

这种方式通过反向遍历索引,再用 array[i] 取值,既实现了反向访问,又保留了索引信息。

适用场景:需要在循环体中使用索引变量时。

5. 使用 downTo() 函数创建递减区间

Kotlin 提供了 downTo() 函数,用于创建一个递减的整数序列。它返回的是 IntProgression 类型,而非 IntRange

区别在于:

  • IntRange 步长固定为 1(或 -1)
  • IntProgression 支持自定义步长

downTo() 本质上就是创建了一个步长为 -1 的 IntProgression

public infix fun Int.downTo(to: Int): IntProgression {
    return IntProgression.fromClosedRange(this, to, -1)
}

因此,我们可以这样写:

val resultList = mutableListOf<String>()
for (i in (array.lastIndex downTo 0)) {
    resultList += array[i]
}
assertEquals(reversedList, resultList)

⚠️ 注意这里的 (array.lastIndex downTo 0) 实际上是调用 array.lastIndex.downTo(0)。由于 downTo 是一个 infix 函数,我们可以省略点号和括号,写成更自然的中缀表达式。

优点:性能高,不生成中间集合,直接控制索引。
缺点:相比 reversed() 稍显啰嗦,但控制力更强。

6. 总结与选型建议

方法 是否需要索引 性能 推荐程度
array.reversed() ❌ 否 ⚠️ 中等(生成新列表) ✅ 首选(无需索引时)
array.indices.reversed() ✅ 是 ✅ 高(仅遍历索引) ✅ 推荐(需要索引时)
array.lastIndex downTo 0 ✅ 是 ✅ 最高(无额外对象) ✅ 推荐(追求极致性能)

📌 总结

  • 如果你只关心元素本身,用 reversed() 最简洁。
  • 如果需要索引,优先考虑 indices.reversed(),语义更清晰。
  • 在性能敏感场景,可使用 downTo(),但注意可读性略有下降。

示例完整代码已托管至 GitHub:https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-arrays-2

踩坑提醒:别把 reversed()reverse() 搞混了!前者返回新列表,后者通常用于原地反转(如 MutableList.reverse())。数组没有原地 reverse() 方法,别白折腾。


原始标题:Iterate Through an Array in Reverse Order in Kotlin