1. 概述
在使用 Kotlin 编程时,我们经常需要操作列表(List)。有时为了数据处理或展示的需要,我们需要将列表元素顺序反转。
Kotlin 提供了两个非常方便的函数来实现这一需求:**reversed()
** 与 **asReversed()
**。
本文将通过示例来讲解这两个函数的使用方式,并深入分析它们之间的区别与适用场景。如果你在实际开发中踩过坑,相信这篇文章会对你有所帮助 ✅
2. reversed()
与 asReversed()
函数简介
我们先来看一个简单的使用示例:
val inputList = listOf("item 1", "item 2", "item 3", "item 4", "item 5")
val expected = listOf("item 5", "item 4", "item 3", "item 2", "item 1")
val result1 = inputList.reversed()
val result2 = inputList.asReversed()
assertEquals(expected, result1)
assertEquals(expected, result2)
从上面的例子可以看出:
- 两个函数都能返回一个元素顺序反转后的列表;
- 用法非常相似;
- 但它们背后的实现机制和行为是不同的。
下面我们分别深入分析这两个函数。
3. reversed()
函数详解
来看一下 reversed()
的源码实现:
public fun <T> Iterable<T>.reversed(): List<T> {
if (this is Collection && size <= 1) return toList()
val list = toMutableList()
list.reverse()
return list
}
关键点如下:
- ✅ 该函数适用于所有
Iterable
类型; - ✅ 返回的是一个 只读的 List;
- ✅ 内部创建了一个新的
MutableList
,并对其进行了原地反转; - ✅ 返回的列表与原始列表无关联,后续对原始列表的修改不会影响到反转后的结果。
我们可以通过一个测试来验证这一点:
val inputList = mutableListOf("item 1", "item 2", "item 3", "item 4", "item 5")
val expected = listOf("item 5", "item 4", "item 3", "item 2", "item 1")
val result = inputList.reversed()
assertEquals(expected, result)
inputList.add("LAST")
assertEquals(expected, result) // result 未变化
✅ 结论:reversed()
返回的是一个全新的列表,与原列表无引用关系。
4. asReversed()
函数详解
再来看 asReversed()
的定义:
public fun <T> MutableList<T>.asReversed(): MutableList<T>
关键点如下:
- ✅ 该函数只能作用于
MutableList
; - ✅ 返回的是一个可变的
MutableList
; - ✅ 返回的列表是原始列表的一个反转视图;
- ✅ 对原始列表或反转后的列表所做的修改都会互相影响。
我们通过测试来验证其行为:
val inputList = mutableListOf("item 1", "item 2", "item 3", "item 4", "item 5")
val expected = mutableListOf("item 5", "item 4", "item 3", "item 2", "item 1")
val result = inputList.asReversed()
assertEquals(expected, result)
// 修改原始列表
inputList.add("LAST")
val expectedAfterChanges = mutableListOf("LAST", "item 5", "item 4", "item 3", "item 2", "item 1")
assertEquals(expectedAfterChanges, result)
// 修改反转后的列表
result.add("FIRST")
assertEquals(listOf("FIRST", "item 1", "item 2", "item 3", "item 4", "item 5", "LAST"), inputList)
✅ 结论:asReversed()
返回的是一个可变视图,与原始列表共享数据,修改是双向同步的。
5. 总结对比
特性 | reversed() |
asReversed() |
---|---|---|
接收类型 | Iterable<T> |
MutableList<T> |
返回类型 | List<T> (只读) |
MutableList<T> |
是否新创建列表 | 是 | 否(视图) |
是否同步变化 | 否 | 是 |
是否可变 | 否 | 是 |
适用场景 | 需要独立副本 | 需要双向同步 |
6. 实际开发建议
- 如果你只是想获取一个反转后的只读列表,并且不希望它与原列表有关系,就使用
reversed()
✅ - 如果你需要一个可变的反转视图,并希望它与原列表保持同步,就使用
asReversed()
✅ - ⚠️ 注意:
asReversed()
只适用于MutableList
,如果传入的是List
会编译错误。
7. 示例代码仓库
文中所有示例代码都可以在 GitHub 上找到: