对于Kotlin中的List,asReversed()本质上是反向()吗?

问题描述 投票:1回答:1

如答案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]

对我来说,这意味着仅当原始列表为MutableList时,它才能在其中更改其值。

但是,如果原始列表是不可变的List,则它的值不能更改,这本质上使asReversed()reversed()在它上面没有明显的区别,对吧?

    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结果都将改变

kotlin collections
1个回答
0
投票

他们的差异实际上让我惊讶!

好吧,通过浏览std-lib,这就是我所发现的。

reversed函数实际上创建一个副本任何Iterable作为MutableList,然后将列表“真正”反转”然后返回它。

public fun <T> Iterable<T>.reversed(): List<T> {
    if (this is Collection && size <= 1) return toList()
    val list = toMutableList()
    list.reverse()
    return list
}

当您调用asReversed()时,它不会“通过复制元素”来创建新列表。

它只是创建一个抽象列表的实现,并将其委托给真实列表,并覆盖吸气剂。

public fun <T> List<T>.asReversed(): List<T> = ReversedListReadOnly(this)

private open class ReversedListReadOnly<out T>(private val delegate: List<T>) : AbstractList<T>() {
    override val size: Int get() = delegate.size
    override fun get(index: Int): T = delegate[reverseElementIndex(index)]
}

因此没有开销,因为列表是不可变的,因此无需触摸任何其他部分,也无需复制列表,即无需创建新列表并分配其内存。它经过简化,仅使用原始列表。

© www.soinside.com 2019 - 2024. All rights reserved.