kotlin中实现json更新处理、json合并处理、最终返回一个完整的 JSON 字符串

现在的 mergeDetailed 返回的是更新后的 Bean 对象,但你想要的是:将 JSON 数据合并到另一个 JSON 中,有就更新,没有就添加,最终返回一个完整的 JSON 字符串

也就是说,你需要一个 JsonObject 级别的合并工具,而不是先转成 Bean 再转回来。


方案:直接合并两个 JSON 字符串

kotlin 复制代码
package com.gzyq.ynlk.util

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser

object JsonMergeUtil {

    val gson = Gson()

    /**
     * 将 sourceJson 合并到 targetJson 中
     * - targetJson 中存在的字段:用 sourceJson 的值覆盖
     * - targetJson 中不存在的字段:从 sourceJson 添加进来
     * - 返回合并后的完整 JSON 字符串
     */
    fun mergeJson(targetJson: String, sourceJson: String): String {
        val target = JsonParser.parseString(targetJson).asJsonObject
        val source = JsonParser.parseString(sourceJson).asJsonObject

        source.entrySet().forEach { (key, value) ->
            target.add(key, value)
        }

        return gson.toJson(target)
    }

    /**
     * 带详细信息的版本,返回合并后的 JSON 字符串 + 变更信息
     */
    fun mergeJsonDetailed(targetJson: String, sourceJson: String): JsonMergeResult {
        val target = JsonParser.parseString(targetJson).asJsonObject
        val source = JsonParser.parseString(sourceJson).asJsonObject

        val targetFields = target.keySet().toList()
        val sourceFields = source.keySet().toList()

        // 记录合并前的值
        val beforeMap = target.toValueMap()

        // 执行合并:source 覆盖/添加到 target
        source.entrySet().forEach { (key, value) ->
            target.add(key, value)
        }

        val afterMap = target.toValueMap()

        // 分析变更
        val updatedFields = sourceFields.filter { key ->
            key in targetFields && beforeMap[key] != afterMap[key]
        }
        val addedFields = sourceFields.filter { it !in targetFields }
        val unchangedFields = sourceFields.filter { key ->
            key in targetFields && beforeMap[key] == afterMap[key]
        }

        return JsonMergeResult(
            mergedJson = gson.toJson(target),
            updatedFields = updatedFields,      // 被修改的字段
            addedFields = addedFields,          // 新增的字段
            unchangedFields = unchangedFields,  // 值未变的字段
            sourceFields = sourceFields,
            targetFields = targetFields
        )
    }

    private fun JsonObject.toValueMap(): Map<String, String> {
        val map = mutableMapOf<String, String>()
        this.entrySet().forEach { (key, element) ->
            map[key] = element.toString()
        }
        return map
    }
}

// 返回结构体
data class JsonMergeResult(
    val mergedJson: String,           // 合并后的完整 JSON 字符串
    val updatedFields: List<String>,   // 被更新的字段(target 中已存在且值变了)
    val addedFields: List<String>,     // 新增的字段(target 中原来没有)
    val unchangedFields: List<String>, // 值未变的字段
    val sourceFields: List<String>,    // source 中的所有字段
    val targetFields: List<String>     // target 中的所有字段
)

使用示例

kotlin 复制代码
fun main() {
    val targetJson = """{"id":1,"user_name":"张三","user_age":25,"email":"test@qq.com"}"""
    val sourceJson = """{"user_name":"李四","user_age":25,"phone":"13800138000","address":"北京"}"""

    val result = JsonMergeUtil.mergeJsonDetailed(targetJson, sourceJson)

    println("合并后的 JSON:")
    println(result.mergedJson)
    // {"id":1,"user_name":"李四","user_age":25,"email":"test@qq.com","phone":"13800138000","address":"北京"}

    println("更新的字段:${result.updatedFields}")      // [user_name]
    println("新增的字段:${result.addedFields}")          // [phone, address]
    println("未变的字段:${result.unchangedFields}")      // [user_age]
}

对比你原来的用法

你的需求 原来的 mergeDetailed 新的 mergeJsonDetailed
输入 Bean + JSON 字符串 JSON 字符串 + JSON 字符串
输出 MergeResult<T>(Bean 对象) JsonMergeResult(JSON 字符串)
适用场景 需要拿到 Bean 对象做后续业务处理 只需要合并 JSON,不关心具体 Bean 类型

如果你还需要保留原来的 Bean 合并功能,可以把两个方法共存,按需使用。

相关推荐
hai_android7 小时前
不用 AIDL,手把手教你手写 Binder 代理类
android·kotlin
雨白11 小时前
Kotlin 泛型进阶:攻克型变与实化,直击痛点
kotlin
谢斯11 小时前
[unity]如何在unity中添加newtonsoft-json
unity·json·游戏引擎
alexhilton15 小时前
架构测试为何需要双视图
android·kotlin·android jetpack
事圆则缓15 小时前
Jetpack Compose 快速上手
android·kotlin
事圆则缓15 小时前
MVC、MVP、MVVM、MVI 的区别与实现原理
android·kotlin·mvc
事圆则缓16 小时前
Android组件化指南
android·kotlin
事圆则缓18 小时前
Jetpack Compose Effect 完全指南
android·kotlin
2601_962066931 天前
短视频批量制作怎么做?2026年用 huasheng-cli 的 --json 与退出码,一张选题表批量出片
json·音视频
我命由我123452 天前
Android Jetpack Compose 开发问题:Unresolved reference ‘Icons‘.
android·java-ee·kotlin·android studio·android jetpack·android-studio·android runtime