【问题标题】:Changes made to one object list takes also affect on another list对一个对象列表所做的更改也会影响另一个列表
【发布时间】:2018-04-03 07:58:38
【问题描述】:

所以,我有一个数据类Cars。 当我第一次开始活动时,我会创建一个列表并添加一些对象:

val listA: ArrayList<Cars> = ArrayList()
listA.add(*API response objects*)

一切都很好,直到我决定创建不同的列表并添加此列表内容(基本上是复制):

val listB: ArrayList<Cars> = ArrayList()
listB.addAll(listA)

然后我决定执行一些删除命令,例如:

if (imFeelingLucky) listB.removeAt(position)

问题:listB 所做的更改也会影响listA(当我从listA 中删除项目时,它会自动从listB 中删除项目)。我错过了什么?为什么会这样?我正在尝试更改列表的“内容”,而不是更改“对象”。如何避免这种情况?


代码:

我有一个二维列表 - 汽车列表,里面有汽车颜色。

原始列表(我想复制元素而不影响这个): 列表A

List<Cars>:
 Car#1:
      *name_of_car
      *car_colors: List<CarColors> ...
 Car#2:
      *name_of_car
      *car_colors: List<CarColors> ...
 Car#3:
      *name_of_car
      *car_colors: List<CarColors> ...

listC​​strong> - 包含汽车的颜色。基本上是for-loop

class testA {

    val listA: ArrayList<Cars> = ArrayList()

    init {
        getData()
        changeData()
    }

    private fun getData() {
        listA.add(..getting data and population listA)
    }

    private fun changeData(): List<Cars> {
        val listB: List<Cars> = ArrayList()
        listB.addAll(listA)

        for (carPosition in listC.size - 1 downTo 0) {
            for (carColorPosition in listC[carPosition].size - 1 downTo 0) {
                if (!listC[carPosition][carColorPosition]) {
                    listB[carPosition].options.removeAt(carColorPosition)
                }
            }
        }

        for (itemToRemovePosition in listB.size - 1 downTo 0) {
            if (listB[itemToRemovePosition] == 0) {
                listB.removeAt(itemToRemovePosition)
            }
        }

        return listB
    }

}

【问题讨论】:

  • 您显示的代码不应该发生这种情况。请提供一个连续的代码块来重现此问题 - 目前,您似乎不小心从其他地方操纵了您的两个列表,我们在上面可能看不到。
  • @zsmb13 更新了代码和附加信息。
  • listB[carPosition].options.removeAt(carColorPosition) -- 在这里您从内部列表中删除一个项目。您没有复制此列表。
  • @MarkoTopolnik 是的,但为什么listB 中的“对象”更改也会影响listA?如果我更改对象,那么它会随处更改(?)-不知道。你会如何建议做内/外列表的优雅副本。
  • @PeteWonder 当您添加所有对象时,它只是将相同的对象添加到两个列表中,您需要做的是一个深拷贝,您可以在其中克隆各个对象并将它们添加到列表中。

标签: kotlin


【解决方案1】:
val listB: List<Cars> = ArrayList()
listB.addAll(listA)

在两个列表中都有相同的 Cars 对象时进行浅拷贝。你需要的是一个深拷贝:

How to clone or copy a list in kotlin

Kotlin data class copy method not deep copying all members

如果最坏的情况出现在最坏的情况下,您可以遍历列表并添加新对象: 即 for (cars in listA) listB.add(Cars(cars.name, cars.options.toMutableList()) 或类似的东西,这里的重点是,对于所有列表中的每个对象,您需要复制它并重新创建列表或使用一些内置方法来执行此操作(如果可用)。

【讨论】:

  • 如果Cars类不是Data class怎么办?
  • 我在答案末尾更新了,您可以为列表中的每个人创建一个新的 Cars 对象
猜你喜欢
  • 2019-11-06
  • 2012-12-13
  • 1970-01-01
  • 2020-06-02
  • 2015-06-29
相关资源
最近更新 更多