什么是深刻复制二维MutableList简洁的方式?

元素已经实现了深度复制。

fun <T : DeepCopiable> f(a: MutableList<MutableList<T>>) { val copied = a.map { it.map { it.deepCopy() }.toMutableList() }.toMutableList() ... } 

我正在使用这种代码,但似乎冗长。

由于类型系统的限制,如果不绕过类型安全性(由于JVM类型的擦除当涉及到泛型时你肯定不想把这个漏洞去掉),这个问题就不能被推广到一个单一的功能。

但是,您可以编写一个实现深度复制模式的扩展函数 ,将每个增加的维度委托给前一个函数,类型安全:

 private typealias I<E> = Iterable<E> private typealias Copy<E> = (E) -> E private inline fun <T, R> I<T>.mapToMutable(transform: (T) -> R): I<R> = mapTo(mutableListOf(), transform) fun <E> I<E>.deepCopy1(c: Copy<E>) = mapToMutable { c(it) } fun <E> I<I<E>>.deepCopy2(c: Copy<E>) = mapToMutable { it.deepCopy1(c) } fun <E> I<I<I<E>>>.deepCopy3(c: Copy<E>) = mapToMutable { it.deepCopy2(c) } fun <E> I<I<I<I<E>>>>.deepCopy4(c: Copy<E>) = mapToMutable { it.deepCopy3(c) } fun <E> I<I<I<I<I<E>>>>>.deepCopy5(c: Copy<E>) = mapToMutable { it.deepCopy4(c) } 

由于JVM类型的擦除,这些功能需要不同的名称( @JVMName由于类型干扰模糊2而不起作用)。 类型别名用于防止水平空间爆炸,并且通过通用复制函数参数将函数集从可深度复制的接口解耦。

用法示例:

 fun main(args: Array<String>) { data class IntHolder(var value: Int) val original = List(3) { a -> List(3) { b -> IntHolder(a + b) } } val copied = original.deepCopy2 { it.copy() } original[0][0].value = 18258125 println("original=$original") println("copied =$copied") } 

– >

 original=[[IntHolder(value=18258125), IntHolder(value=1), IntHolder(value=2)], [IntHolder(value=1), IntHolder(value=2), IntHolder(value=3)], [IntHolder(value=2), IntHolder(value=3), IntHolder(value=4)]] copied =[[IntHolder(value=0), IntHolder(value=1), IntHolder(value=2)], [IntHolder(value=1), IntHolder(value=2), IntHolder(value=3)], [IntHolder(value=2), IntHolder(value=3), IntHolder(value=4)]] 

[1]:因为泛型类型强制转换在运行时由编译器执行,所以从List<Foo>List<Baz>强制转换在运行时总是成功的,但是在访问转换后的列表之后会失败。 实现提到的魔术“单一功能”是可能的,但是最微小的错误将导致返回的数据结构在类别转换异常访问时看似“随机”失败。

[2]:类型Iterable<Iterable<Foo>>满足两者

fun <T> Iterable<T>.baz() (T = Iterable<Foo> )和
fun <T> Iterable<Iterable<T>.baz() (T = Foo

因此,如果链中的所有方法具有相同的函数名称,但是具有不同的JVM名称,则编译器将无法确定正确的方法。

[3]:

 Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<ithinkyougetthepoint>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 

这是一个使用java.lang.reflect.Array & java.lang.Cloneable的简单深层拷贝示例。

Noet : 克隆方法执行此对象的浅表副本,而不是深层复制操作,但可以覆盖克隆方法以提供深层复制操作,例如:

 val list = mutableListOf(mutableListOf(arrayOf(1))) val copied = list.deepCopy() println(copied !== list) //true: not the same println(copied.map{it.map{it.toList()}} == list.map{it.map{it.toList()}}) // ^---true: content equals // v--- Array is cloned, since it has implemented Cloneable println(copied[0][0] !== array[0][0]) // true 

 typealias NativeArray = java.lang.reflect.Array @Suppress("UNCHECKED_CAST") fun <T> T.deepCopy(): T { return when (this) { is Array<*> -> { val type = this.javaClass.componentType NativeArray.newInstance(type, size).also { this.forEachIndexed { i, item -> NativeArray.set(it, i, item.deepCopy()) } } as T } is MutableList<*> -> this.mapTo(mutableListOf()) { it.deepCopy() } as T is List<*> -> this.map { it.deepCopy() } as T is Cloneable -> this.javaClass.getDeclaredMethod("clone").let { it.isAccessible = true; it.invoke(this) as T } else -> this } }