Kotlin深拷贝代码


import java.util.*
import kotlin.collections.ArrayList
import kotlin.reflect.full.createInstance
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.javaField

/**
 * @Description: 用来复制元素的工具类
 * @Author: dk
 * @Date: 2021/6/28 12:05 PM
 * @Gmail: dk.guo@tron.network
 */
fun <T : Any> T.deepCopy(): T {
    val copiedObjects = mutableMapOf<Any, Any>()
    return deepCopy(this, copiedObjects)
}

private fun <T : Any> deepCopy(obj: T, copiedObjects: MutableMap<Any, Any>): T {

    val objClassJava = obj::class.java
    val objClass = obj::class

    // 基本数据类型直接返回
    if (objClassJava.isPrimitive) {
        return obj
    } else {
        if (objClass.javaPrimitiveType != null) {
            return obj
        }
    }

    when (obj) {
        is String -> {
            val newString = String(obj.toCharArray())
            copiedObjects[obj] = newString
            return newString as T
        }
        is Array<*> -> {
            val arrList = ArrayList<Any?>()
            val newArray: Any

            for (elem in obj) {
                if (elem == null)
                    arrList.add(elem)
                else
                    arrList.add(getValueFromCopiedCollection(elem, copiedObjects))
            }
            newArray = obj.clone()
            arrList.toArray(newArray)
            copiedObjects[obj] = newArray
            return newArray as T
        }
        is List<*> -> {
            val arrList = ArrayList<Any?>()
            for (elem in obj) {
                if (elem == null)
                    arrList.add(elem)
                else
                    arrList.add(getValueFromCopiedCollection(elem, copiedObjects))
                copiedObjects[obj] = arrList
            }
            return arrList as T
        }
        is Map<*, *> -> {
            val newMap = mutableMapOf<Any?, Any?>()
            for ((key, value) in obj) {
                if (key == null) {
                    if (value == null)
                        newMap[key] = value
                    else
                        newMap[key] = getValueFromCopiedCollection(value, copiedObjects)
                } else {
                    if (value === null)
                        newMap[getValueFromCopiedCollection(key, copiedObjects)] = value
                    else
                        newMap[getValueFromCopiedCollection(key, copiedObjects)] = getValueFromCopiedCollection(value, copiedObjects)
                }
            }
            copiedObjects[obj] = newMap
            return newMap as T
        }
        is Set<*> -> {
            val newSet = mutableSetOf<Any?>()
            for (elem in obj) {
                if (elem == null)
                    newSet.add(elem)
                else
                    newSet.add(getValueFromCopiedCollection(elem, copiedObjects))
            }
            copiedObjects[obj] = newSet
            return newSet as T
        }
        is Date -> {
            return Date(obj.time) as T
        }
        else -> {
            val properties = objClass.memberProperties
            val newCopy = objClassJava.newInstance()

            properties.forEach { prop ->
                val field = prop.javaField
                if (field != null) {
                    field.isAccessible = true
                    val value = field.get(obj)
                    if (value == null)
                        field.set(newCopy, value)
                    else
                        field.set(newCopy, getValueFromCopiedCollection(value, copiedObjects))
                }
            }
            copiedObjects[obj] = newCopy
            return newCopy
        }
    }
}

private fun <T : Any> getValueFromCopiedCollection(value: T, copiedObjects: MutableMap<Any, Any>): T {

    if (copiedObjects.containsKey(value)) {
        return copiedObjects[value] as T
    }

    var tempValue: Any? = null
    if (!value::class.java.isPrimitive
            && value::class.javaPrimitiveType == null
            && !value::class.java.isArray
            && (value !is Collection<*>)) {

        tempValue = value::class.createInstance()
    }

    if (copiedObjects.isNotEmpty()) {
        tempValue = deepCopy(value, copiedObjects)
    }

    if (tempValue == null || tempValue != value)
        tempValue = value
    else
        copiedObjects[value] = tempValue

    return tempValue as T
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值