对象之间(包含父类私有属性),属性批量赋值(替换) /declaredFields /field

主要是通过反射实现,对比两个对象之中相同属性名的值是否一致,然后按照既定规则进行赋值,或者不处理。
如果有更复杂的交互逻辑,可以根据这中代码能力进行拓展。

通用方法代码


/**
 * [to] 把取的值尝试放到这里
 * [emptyReplacement] 如果取的值是空的,是否也需要替换,默认不需要
 *
 * use : 需要取值的对象.propertyTo(需要把值放入的对象,空值是否也需要替换)
 *
 */
fun Any?.propertyTo(to: Any?, emptyReplacement: Boolean = false) {
    val from = this
    if (from == null || to == null) return
    propertyToChildren(from, to, emptyReplacement)
}

/**
 * 属性替换方法
 * [sFromFields] 取值对象的所有私有属性
 * [rf] 原取值对象
 * [rt] 原设置对象
 * [sTo] 当前设置对象(可能是原设置对象的父类,或者自己)
 */
private fun valueExChange(sFromFields: Array<Field>, rf: Any, rt: Any, sTo: Class<*>, emptyReplacement: Boolean = false) {
    try {
        for (field in sFromFields) {
            field.isAccessible = true
            val value: Any? = field.get(rf)
            if (emptyReplacement || (null != value && "" != value)) {
                try {
                    val toField: Field = sTo.getDeclaredField(field.name)
                    if (field.type.toString() == toField.type.toString()) {
                        toField.isAccessible = true
                        val toValue = toField.get(rt)
                        if (toValue != value) {
                            toField.set(rt, value)
                        }
                    }
                } catch (e: NoSuchFieldException) {
                    // 这里是找不到这个property,不用管
                }
            }
        }
    } catch (ignored: Exception) {
    }
}

/**
 * 对当前类进行属性转换
 */
private fun propertyToChildren(from: Any, to: Any, emptyReplacement: Boolean = false) {
    val fields: Array<Field> = from.javaClass.declaredFields
    valueExChange(fields, from, to, to.javaClass, emptyReplacement)
    looperParent(from, to, from.javaClass, to.javaClass, emptyReplacement)
}

/**
 * 递归转换当前类的各级父类
 */
private fun looperParent(rf: Any, rt: Any,  from: Class<*>?, to: Class<*>?, emptyReplacement: Boolean = false) {
    if (from == null || to == null) return
    if (from.superclass != null && to.superclass != null
        && "class java.lang.Object" != from.superclass.toString()
        && "class java.lang.Object" != to.superclass.toString()
    ) {
        val sFrom = Class.forName((from.superclass as Class).name)
        val sFromFields =  sFrom.declaredFields
        val sTo =  Class.forName((to.superclass as Class).name)
        valueExChange(sFromFields, rf, rt, sTo, emptyReplacement)
        looperParent(rf, rt, sFrom, sTo, emptyReplacement)
    }
}

测试代码

object TestDiff {

    @JvmStatic
    fun main(args: Array<String>) {
        val old = TestEntity(
            "这是旧的", 1,false,1L,1F,1.0, listOf(TestChildrenArrayEntity("旧的", "旧内容")),mutableListOf(TestChildrenArrayEntity("旧的", "旧内容")),
            TestChildrenEntity("旧标题", "旧文本")
        )

        print("旧数据是:")
        print(old)
        print("\n\n")

        val new = TestEntity2(
            "", 2, true, 2L, 2F, 2.0, null, mutableListOf(TestChildrenArrayEntity("新的", "新内容")),
            TestChildrenEntity("新标题", "新文本")
        )

        print("新数据是:")
        print(new)
        print("\n\n")

        print("开始对比替换:\n")
        new.propertyTo(old, true)
        print("结束!\n")

        print("旧数据:")
        print(old)
        print("\n新数据:")
        print(new)
    }
}

data class TestEntity(
    val string: String?,
    val int: Int,
    val boolean: Boolean,
    val long : Long,
    val float: Float,
    val double: Double,
    val list: List<TestChildrenArrayEntity>?,
    val mutableList: MutableList<TestChildrenArrayEntity>?,
    val entity: TestChildrenEntity?
)

data class TestEntity2(
    val strings: String?,
    val ints: Int,
    val booleans: Boolean,
    val long : Long,
    val float: Float,
    val double: Double,
    val list: List<TestChildrenArrayEntity>?,
    val mutableList: MutableList<TestChildrenArrayEntity>?,
    val entity: TestChildrenEntity?
)

data class TestChildrenEntity(val title: String, val content: String)
data class TestChildrenArrayEntity(val title: String, val content: String)

执行日志输出

旧数据是:TestEntity(string=这是旧的, int=1, boolean=false, long=1, float=1.0, double=1.0, list=[TestChildrenArrayEntity(title=旧的, content=旧内容)], mutableList=[TestChildrenArrayEntity(title=旧的, content=旧内容)], entity=TestChildrenEntity(title=旧标题, content=旧文本))

新数据是:TestEntity2(strings=, ints=2, booleans=true, long=2, float=2.0, double=2.0, list=null, mutableList=[TestChildrenArrayEntity(title=新的, content=新内容)], entity=TestChildrenEntity(title=新标题, content=新文本))

开始对比替换:
结束!
旧数据:TestEntity(string=这是旧的, int=1, boolean=false, long=2, float=2.0, double=2.0, list=null, mutableList=[TestChildrenArrayEntity(title=新的, content=新内容)], entity=TestChildrenEntity(title=新标题, content=新文本))
新数据:TestEntity2(strings=, ints=2, booleans=true, long=2, float=2.0, double=2.0, list=null, mutableList=[TestChildrenArrayEntity(title=新的, content=新内容)], entity=TestChildrenEntity(title=新标题, content=新文本))
Process finished with exit code 0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值