如何克隆或复制一个列表在kotlin

如何在Kotlin复制列表?

我使用

val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)

有没有更简单的方法?

132489 次浏览

这很好。

val selectedSeries = series.toMutableList()

我可以想出两种方法:

1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }


2. val selectedSeries = mutableListOf(*series.toTypedArray())

更新:使用新的类型推断引擎(在Kotlin 1.3中可选),我们可以省略第一个例子中的泛型类型参数,并得到:

1. val selectedSeries = mutableListOf().apply { addAll(series) }

仅供参考。选择新推理的方法是kotlinc -Xnew-inference ./SourceCode.kt命令行,或kotlin { experimental { newInference 'enable'} Gradle。有关新的类型推断的更多信息,请查看此视频:KotlinConf 2018 -新的类型推断和相关语言功能由Svetlana Isakova,特别是' Inference For builders' at 30'

你可以使用

List -> toList()

数组-> toArray()

ArrayList -> toArray()

MutableList -> toMutableList()


例子:

val array = arrayListOf("1", "2", "3", "4")


val arrayCopy = array.toArray() // copy array to other array


Log.i("---> array " ,  array?.count().toString())
Log.i("---> arrayCopy " ,  arrayCopy?.count().toString())


array.removeAt(0) // remove first item in array


Log.i("---> array after remove" ,  array?.count().toString())
Log.i("---> arrayCopy after remove" ,  arrayCopy?.count().toString())

打印日志:

array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4

我建议你做个肤浅的拷贝

.map{it}

这将适用于许多收集类型。

如果你的列表包含Kotlin数据类,你可以这样做

selectedSeries = ArrayList(series.map { it.copy() })

我将使用toCollection()扩展方法:

val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())

这将创建一个新的MutableList,然后将原始的每个元素添加到新创建的列表中。

这里的推断类型将是MutableList<String>。如果你不想暴露这个新列表的可变性,你可以显式地将该类型声明为一个不可变列表:

val copy: List<String> = original.toCollection(mutableListOf())

就像在Java中一样:

列表:

    val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)

地图:

    val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)

假设你的目标是JVM(或Android);我不确定它是否适用于其他目标,因为它依赖于ArrayList和HashMap的复制构造函数。

对于简单的列表,上面有许多正确的解决方案。

然而,它只是用于较浅的列表。

下面的函数适用于任何2维ArrayListArrayList实际上相当于MutableList。有趣的是,它在使用显式MutableList类型时不起作用。如果一个人需要更多的维度,就需要更多的函数。

fun <T>cloneMatrix(v:ArrayList<ArrayList<T>>):ArrayList<ArrayList<T>>{
var MatrResult = ArrayList<ArrayList<T>>()
for (i in v.indices) MatrResult.add(v[i].clone() as ArrayList<T>)
return MatrResult
}

演示整数矩阵:

var mat = arrayListOf(arrayListOf<Int>(1,2),arrayListOf<Int>(3,12))
var mat2 = ArrayList<ArrayList<Int>>()
mat2 = cloneMatrix<Int>(mat)
mat2[1][1]=5
println(mat[1][1])

它显示12

尝试下面的代码复制列表在芬兰湾的科特林

arrayList2.addAll(arrayList1.filterNotNull())

你可以使用提供的扩展Iterable.toMutableList(),它将为你提供一个新的列表。不幸的是,正如它的签名和文档所表明的,它意味着确保IterableList(就像toString和许多其他to<type>方法一样)。没有什么能保证它将是一个列表。例如,在扩展名的开头添加以下一行:if (this is List) return this是一个合理的性能改进(如果它确实提高了性能)。

另外,由于它的名字,结果代码不是很清楚。

我更喜欢添加自己的扩展,以确保结果并创建更清晰的代码(就像我们对数组所做的那样):

fun <T> List<T>.copyOf(): List<T> {
return mutableListOf<T>().also { it.addAll(this) }
}


fun <T> List<T>.mutableCopyOf(): MutableList<T> {
return mutableListOf<T>().also { it.addAll(this) }
}

注意,addAll是最快的复制方式,因为它在ArrayList的实现中使用了本机System.arraycopy

另外,注意这只会给你一个浅拷贝

编辑:

你可能想要使用更通用的版本:

fun <T> Collection<T>.copyOf(): Collection<T> {
return mutableListOf<T>().also { it.addAll(this) }
}


fun <T> Collection<T>.mutableCopyOf(): MutableCollection<T> {
return mutableListOf<T>().also { it.addAll(this) }
}

你可以使用ArrayList构造函数:ArrayList(list)

val selectedSeries = listOf(*series.toTypedArray())

在尝试浅拷贝,深拷贝克隆和更多的我发现这个解决方案肯定会为你工作。

val iterator: Iterator<Object> = yourList.iterator()
while (iterator.hasNext())
newList.add(iterator.next().copy())
var oldList: List<ClassA>?
val newList = oldList.map { it.copy() }