
本教程详细介绍了如何在 Java 中高效地合并和更新两个 JSON 数组中的对象。针对需要根据多个共享键(如 userid 和 scripcode)同步数据的情况,我们探讨了传统嵌套循环方法的局限性,并重点推荐使用功能强大的 Josson 库。通过 Josson 提供的 SQL 风格查询语言,可以简洁明了地实现复杂的左连接与字段更新操作,显著提升代码可读性和处理效率。
引言:JSON 数组合并与更新的挑战
在数据处理中,我们经常会遇到需要将两个或多个 json 数组进行合并或更新的场景。例如,一个主数据数组(http)需要根据另一个更新数据数组(websocketjsonarray)中的信息来更新其内部对象的特定字段。这种更新通常基于一个或多个共享的唯一标识符(如 userid 和 scripcode)。
传统的做法是使用嵌套循环遍历两个数组,并在内层循环中进行条件判断和数据更新。然而,这种方法存在以下弊端:
代码冗余且复杂:嵌套循环和大量的条件判断会使代码变得冗长且难以维护。易出错:手动管理索引和字段访问容易引入逻辑错误,例如原始问题中将 websocketjsonArray.getJSONObject(l) 误写为 websocketjsonArray.getJSONObject(k)。性能问题:对于大型数据集,O(n*m) 的时间复杂度可能导致性能瓶颈。
为了克服这些挑战,我们可以借助专门的 JSON 处理库,例如 Josson,它提供了更声明式、更高效的数据操作方式。
Josson 库简介
Josson 是一个功能强大的 Java 库,专门用于处理 JSON 数据。它允许开发者使用类似 SQL 的查询语言对 JSON 对象和数组进行复杂的查询、转换和操作。Josson 的核心优势在于其简洁的语法和高效的内部实现,尤其适用于数据聚合、筛选和连接等场景。
引入 Josson 依赖
要在您的 Java 项目中使用 Josson 库,您需要将其添加到项目的依赖中。如果您使用 Maven,可以在 pom.xml 文件中添加以下依赖:
立即学习“Java免费学习笔记(深入)”;
com.octomix.josson josson 1.3.1
如果您使用 Gradle,可以在 build.gradle 文件中添加:
implementation 'com.octomix.josson:josson:1.3.1' // 请检查Maven Central获取最新版本
使用 Josson 进行 JSON 数组更新
下面我们将演示如何使用 Josson 库,根据 userid 和 scripcode 两个键,将 websocketjsonArray 中的 bfqty 字段值更新到 http 数组对应的对象中。
1. 数据准备
首先,我们需要将原始的 JSON 字符串解析为 Josson 库可操作的 JsonNode 对象,并将其存储在 Jossons 容器中。Jossons 允许您管理多个命名的数据集,方便进行跨数据集的操作。
import com.fasterxml.jackson.databind.JsonNode;import com.octomix.josson.Josson;import com.octomix.josson.Jossons;import org.json.JSONArray;import org.json.JSONException;public class JsonArrayUpdater { public static void main(String[] args) { try { // 原始的 http JSON 数组 JSONArray httpArray = new JSONArray("[{"userid":"CNRM04","groupname":"Rohit"," + ""segment":"CosPROFIN","accountcode":"OWN","symbol":"NIFTY","exchange":"NSEFO"," + ""expirydate":"03NOV2022","scripcode":"38021","securitytype":"OPT"," + ""strikeprice":17700,"opttype":"PE","bfqty":-1500,"bfrate":122.35," + ""bfamt":18352.5,"buyqty":0,"sellqty":0,"netqty":0,"cfqty":-150," + ""cfamt":18352.5,"ltp":0,"grossmtm":0,"brokerageamt":0,"netmtm":0," + ""currency":"INR","usdrate":1,"clientsharing":0,"broksharing":0," + ""comsharing":100,"multiplier":1},{"userid":"CNRM04","groupname":"Rohit"," + ""segment":"CosPROFIN","accountcode":"OWN","symbol":"NIFTY"," + ""exchange":"NSEFO","expirydate":"03NOV2022","scripcode":"38026"," + ""securitytype":"OPT","strikeprice":17800,"opttype":"PE","bfqty":0," + ""bfrate":0,"bfamt":0,"buyqty":10800,"sellqty":15000,"netqty":-4200," + ""cfqty":-4200,"cfamt":590729.9999999998,"ltp":0,"grossmtm":0," + ""brokerageamt":3400.2888479999992,"netmtm":0,"currency":"INR"," + ""usdrate":1,"clientsharing":0,"broksharing":0,"comsharing":100," + ""multiplier":11},{"userid":"CNC01","groupname":"abhishek"," + ""segment":"Cosmic","accountcode":"APP","symbol":"NIFTY"," + ""exchange":"NSEFO","expirydate":"03NOV2022","scripcode":"40034"," + ""securitytype":"OPT","strikeprice":1200,"opttype":"PE","bfqty":12," + ""bfrate":2,"bfamt":0,"buyqty":100,"sellqty":121,"netqty":200," + ""cfqty":11,"cfamt":78,"ltp":9,"grossmtm":0,"brokerageamt":12222," + ""netmtm":45,"currency":"INR","usdrate":2,"clientsharing":0,"broksharing":0,"comsharing":0," + ""multiplier":99}]"); // 用于更新的 websocket JSON 数组 JSONArray websocketArray = new JSONArray("[{"userid":"CNRM04","groupname":"Rohit","segment":"CosPROFIN","accountcode":"OWN","symbol":"NIFTY","exchange":"NSEFO","expirydate":"03NOV2022","scripcode":"38021","securitytype":"OPT","strikeprice":17700,"opttype":"PE","bfqty":20,"bfrate":122.35,"bfamt":18352.5,"buyqty":0,"sellqty":0,"netqty":0,"cfqty":-150,"cfamt":18352.5,"ltp":0,"grossmtm":0,"brokerageamt":0,"netmtm":0,"currency":"INR","usdrate":1,"clientsharing":0,"broksharing":0,"comsharing":100,"multiplier":1},{"userid":"CNRM04","groupname":"Rohit","segment":"CosPROFIN","accountcode":"OWN","symbol":"NIFTY","exchange":"NSEFO","expirydate":"03NOV2022","scripcode":"38026","securitytype":"OPT","strikeprice":17800,"opttype":"PE","bfqty":30,"bfrate":0,"bfamt":0,"buyqty":10800,"sellqty":15000,"netqty":-4200,"cfqty":-4200,"cfamt":590729.9999999998,"ltp":0,"grossmtm":0,"brokerageamt":3400.2888479999992,"netmtm":0,"currency":"INR","usdrate":1,"clientsharing":0,"broksharing":0,"comsharing":100,"multiplier":1}]]"); // 创建 Jossons 实例并加载数据集 Jossons jossons = new Jossons(); jossons.putDataset("http", Josson.fromJsonString(httpArray.toString())); jossons.putDataset("websocket", Josson.fromJsonString(websocketArray.toString())); System.out.println("原始 http 数组:n" + jossons.getDataset("http").toPrettyString()); System.out.println("n原始 websocket 数组:n" + jossons.getDataset("websocket").toPrettyString()); // 执行左连接操作并更新数据 JsonNode updatedHttp = jossons.evaluateQuery( "http{userid,scripcode} <=map(userid,scripcode,bfqty){userid,scripcode}"); System.out.println("n更新后的 http 数组:n" + updatedHttp.toPrettyString()); } catch (JSONException e) { e.printStackTrace(); } }}
2. 核心操作:左连接与字段更新
Josson 提供了强大的查询语言来执行数据操作。在这个例子中,我们使用了一个左连接(<=<)操作符,它类似于 SQL 中的 LEFT JOIN,但更侧重于更新左侧数据集的字段。
核心查询语句是:http{userid,scripcode} <=map(userid,scripcode,bfqty){userid,scripcode}
让我们分解这个查询:
http{userid,scripcode}:这指定了左侧的数据集为 http,并且括号中的 userid,scripcode 定义了用于连接的键。Josson 会根据这些键来匹配 http 数组中的对象。<=map(userid,scripcode,bfqty):这定义了右侧的数据集及其处理方式。websocket:右侧的数据集名称。->map(userid,scripcode,bfqty):这是一个转换操作,它将 websocket 数组中的每个对象转换为一个临时的映射(map)。这个映射的键由 userid 和 scripcode 组成(它们是复合键),而映射的值是一个包含 userid、scripcode 和 bfqty 字段的对象。这种转换使得 Josson 能够高效地通过这些键进行查找并提取 bfqty 值。{userid,scripcode} (在 map 之后):这再次指定了用于匹配右侧数据集(经过 map 转换后的数据)的键。
工作原理总结:Josson 会遍历 http 数组中的每个对象。对于每个 http 对象,它会提取其 userid 和 scripcode 的值,然后使用这些值作为键,在 websocket 数组经过 map 转换后形成的查找表中寻找匹配项。如果找到匹配项,则 websocket 对象中的 bfqty 字段的值将被用来更新 http 对象中相应的 bfqty 字段。如果未找到匹配项,http 对象将保持不变。
3. 输出结果分析
运行上述代码,您将看到如下的输出:
原始 http 数组:[ { "userid" : "CNRM04", "groupname" : "Rohit", "segment" : "CosPROFIN", "accountcode" : "OWN", "symbol" : "NIFTY", "exchange" : "NSEFO", "expirydate" : "03NOV2022", "scripcode" : "38021", "securitytype" : "OPT", "strikeprice" : 17700, "opttype" : "PE", "bfqty" : -1500, // 原始值为 -1500 "bfrate" : 122.35, "bfamt" : 18352.5, "buyqty" : 0, "sellqty" : 0, "netqty" : 0, "cfqty" : -150, "cfamt" : 18352.5, "ltp" : 0, "grossmtm" : 0, "brokerageamt" : 0, "netmtm" : 0, "currency" : "INR", "usdrate" : 1, "clientsharing" : 0, "broksharing" : 0, "comsharing" : 100, "multiplier" : 1}, { "userid" : "CNRM04", "groupname" : "Rohit", "segment" : "CosPROFIN", "accountcode" : "OWN", "symbol" : "NIFTY", "exchange" : "NSEFO", "expirydate" : "03NOV2022", "scripcode" : "38026", "securitytype" : "OPT", "strikeprice" : 17800, "opttype" : "PE", "bfqty" : 0, // 原始值为 0 "bfrate" : 0, "bfamt" : 0, "buyqty" : 10800, "sellqty" : 15000, "netqty" : -4200, "cfqty" : -4200, "cfamt" : 590729.9999999998, "ltp" : 0, "grossmtm" : 0, "brokerageamt" : 3400.2888479999992, "netmtm" : 0, "currency" : "INR", "usdrate" : 1, "clientsharing" : 0, "broksharing" : 0, "comsharing" : 100, "multiplier" : 11}, { "userid" : "CNC01", "groupname" : "abhishek", "segment" : "Cosmic", "accountcode" : "APP", "symbol" : "NIFTY", "exchange" : "NSEFO", "expirydate" : "03NOV2022", "scripcode" : "40034", "securitytype" : "OPT", "strikeprice" : 1200, "opttype" : "PE", "bfqty" : 12, "bfrate" : 2, "bfamt" : 0, "buyqty" : 100, "sellqty" : 121, "netqty" : 200, "cfqty" : 11, "cfamt" : 78, "ltp"
以上就是Java 中基于多键合并与更新 JSON 数组的教程的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/120574.html
微信扫一扫
支付宝扫一扫