如何使用Java更新含嵌套数组的JSON文件中的对象
处理JSON-Simple中嵌套数组/对象的修改与追加问题
我完全懂你的困扰——JSON-Simple处理这种多层嵌套的结构时,确实比简单的键值对复杂不少,网上的基础例子大多只覆盖单层结构,碰到User→Goals→Milestones这种嵌套就抓瞎了。下面我结合实际场景,给你一步步拆解怎么实现修改特定块和追加内容:
首先先明确JSON-Simple的核心类型对应关系:
- JSON数组(
[])对应JSONArray,本质是List<Object>的实现 - JSON对象(
{})对应JSONObject,本质是Map<String, Object>的实现
所有嵌套节点的操作,本质就是逐层向下遍历、类型转换,找到目标节点后再做修改/追加。
场景1:修改特定User下的某个Milestone内容
假设我们要找到id为1的User,再找到他goalName为"Q3业绩目标"的Goal,最后修改其中milestoneId为2的Milestone的status为"完成"。
import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import java.io.FileReader; import java.io.FileWriter; public class JsonModifyDemo { public static void main(String[] args) throws Exception { // 1. 解析JSON文件到顶层数组(Users数组) JSONParser parser = new JSONParser(); JSONArray users = (JSONArray) parser.parse(new FileReader("users.json")); // 2. 遍历找到目标User for (Object userObj : users) { JSONObject user = (JSONObject) userObj; if ("1".equals(user.get("id").toString())) { // 假设User的id是字符串类型 // 3. 获取该User的Goals数组 JSONArray goals = (JSONArray) user.get("Goals"); if (goals == null) continue; // 避免空指针 // 4. 遍历找到目标Goal for (Object goalObj : goals) { JSONObject goal = (JSONObject) goalObj; if ("Q3业绩目标".equals(goal.get("goalName").toString())) { // 5. 获取该Goal的Milestones数组 JSONArray milestones = (JSONArray) goal.get("Milestones"); if (milestones == null) continue; // 6. 遍历找到目标Milestone并修改 for (Object milestoneObj : milestones) { JSONObject milestone = (JSONObject) milestoneObj; if ("2".equals(milestone.get("milestoneId").toString())) { milestone.put("status", "完成"); break; // 找到目标后退出循环 } } break; } } break; } } // 7. 将修改后的内容写回JSON文件 try (FileWriter writer = new FileWriter("users.json")) { writer.write(users.toJSONString()); writer.flush(); } } }
场景2:向指定User的Goals数组追加新Goal
如果要给id为1的User新增一个Goal,包含两个Milestone:
// 接上面的解析步骤,找到目标User后: JSONObject newGoal = new JSONObject(); newGoal.put("goalName", "Q4学习目标"); newGoal.put("deadline", "2024-12-31"); // 给新Goal创建Milestones数组 JSONArray newMilestones = new JSONArray(); JSONObject milestone1 = new JSONObject(); milestone1.put("milestoneId", "3"); milestone1.put("content", "完成Java高级特性学习"); milestone1.put("status", "未开始"); JSONObject milestone2 = new JSONObject(); milestone2.put("milestoneId", "4"); milestone2.put("content", "完成SpringBoot项目实战"); milestone2.put("status", "未开始"); newMilestones.add(milestone1); newMilestones.add(milestone2); newGoal.put("Milestones", newMilestones); // 追加到目标User的Goals数组,如果数组不存在先创建 if (goals == null) { goals = new JSONArray(); user.put("Goals", goals); } goals.add(newGoal); // 最后同样写回文件...
关键注意事项
- 类型强制转换:JSON-Simple的所有节点都是
Object类型,必须手动转成JSONObject或JSONArray才能操作,转换前最好加空判断,避免ClassCastException或NullPointerException - 遍历效率:如果数据量很大,每次遍历查找会比较慢,建议提前给User、Goal、Milestone的唯一标识建立映射(比如用HashMap存id到对象的映射),后续操作直接通过映射查找
- 格式化输出:默认
toJSONString()输出的是压缩格式,如果需要可读性强的格式化输出,可以用JSONValue.toJSONString(users, "\t")(第二个参数是缩进符)
内容的提问来源于stack exchange,提问作者btrballin
相关产品推荐
相关产品推荐

