首页 > 解决方案 > 对于 Kotlin 中的 List,asReversed() 本质上是 reversed() 吗?

问题描述

如答案https://stackoverflow.com/a/57115894/3286489中所述,asReversed()将生成一个反向列表,如果原始列表已更改其元素,则该值将更改。

    val list = mutableListOf(0, 1, 2, 3, 4, 5)
    val asReversed = list.asReversed()
    val reversed   = list.reversed()
    println("Original list: $list")
    println("asReversed:    $asReversed")
    println("reversed:      $reversed")

    list[0] = 10

    println("Original list: $list")
    println("asReversed:    $asReversed")
    println("reversed:      $reversed")

输出

Original list: [0, 1, 2, 3, 4, 5]
asReversed:    [5, 4, 3, 2, 1, 0]
reversed:      [5, 4, 3, 2, 1, 0]
Original list: [10, 1, 2, 3, 4, 5]
asReversed:    [5, 4, 3, 2, 1, 10]
reversed:      [5, 4, 3, 2, 1, 0]

对我来说,这意味着只有当原始列表是 aMutableList时,它才能改变它的值。

但是,如果原始 List 是一个 immutable List,它的值就不能改变,这本质asReversed()reversed()没有明显的区别,对吧?

IE

    val list = listOf(0, 1, 2, 3, 4, 5)
    val asReversed = list.asReversed() // This is the same as below?
    val reversed   = list.reversed()   // This is the same as above?

我错过了他们仍然不同的任何场景吗?

更新 了我什至将它包含的内容更改为mutableList

     val list = listOf(
            mutableListOf(1), 
            mutableListOf(2), 
            mutableListOf(3), 
            mutableListOf(4), 
            mutableListOf(5), 
            mutableListOf(6))
        val asReversed = list.asReversed()
        val reversed   = list.reversed()
        println("Original list: $list")
        println("asReversed:    $asReversed")
        println("reversed:      $reversed")

        list[0][0] = 10

        println("Original list: $list")
        println("asReversed:    $asReversed")
        println("reversed:      $reversed")

输出

Original list: [[1], [2], [3], [4], [5], [6]]
asReversed:    [[6], [5], [4], [3], [2], [1]]
reversed:      [[6], [5], [4], [3], [2], [1]]
Original list: [[5], [2], [3], [4], [5], [6]]
asReversed:    [[6], [5], [4], [3], [2], [10]]
reversed:      [[6], [5], [4], [3], [2], [10]]

这将改变两者asReversedreversed结果

标签: kotlincollections

解决方案


两者之间最重要的区别是,那asReversed始终只是原始列表上的一个视图。这意味着,如果您更改原始列表,结果asReversed将始终包含所有更新的信息。最后只是一个风景。

reversed但是总是给你一个原始列表的新断开列表。但是请注意,当您处理原始列表中的对象引用时(例如列表中的列表或其他类型的可引用对象),您将看到该列表的原始对象的所有改编也适用于反转的对象,无论无论您使用reversed还是asReversed.

关于您的更新,不幸的是您使用了这样一个包含参考的列表。但是,使用您的原始列表,差异变得更加清晰:

val asReversed = list.asReversed()
val reversed = list.reversed()

fun printAll(msg : String) {
  println(msg)
  println("Original list: $list")
  println("asReversed:    $asReversed")
  println("reversed:      $reversed")
}
printAll("Initial ----")

list as MutableList
list[2] = 1000
printAll("mutating original list ----")

reversed as MutableList
reversed[4] = 3000
printAll("mutating reversed list ----")

asReversed返回一个ReversedListReadOnly-type 时,你不能轻易地将它转换为 a MutableList,但如果可能的话,更改asReversed将反映在原始列表中,但不会反映在reversed. 上面的输出如下:

Initial ----
Original list: [0, 1, 2, 3, 4, 5]
asReversed:    [5, 4, 3, 2, 1, 0]
reversed:      [5, 4, 3, 2, 1, 0]
mutating original list ----
Original list: [0, 1, 1000, 3, 4, 5]
asReversed:    [5, 4, 3, 1000, 1, 0]
reversed:      [5, 4, 3, 2, 1, 0]
mutating reversed list ----
Original list: [0, 1, 1000, 3, 4, 5]
asReversed:    [5, 4, 3, 1000, 1, 0]
reversed:      [5, 4, 3, 2, 3000, 0]

如您所见:更改很好地反映在原始列表和asReversed-list 中,但未reversed反映更改,并且反转的更改将不包含原始列表改编。

所以,是的,你可能错过了那个场景......如果你有一个只读视图作为输入,列表 (reversedasReversed) 不相等,甚至不相等,因为没有人可以保证你的列表没有被改变......原来的也不是那个asReversed


推荐阅读