You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON扁平化工具仅返回users数组最后一个对象,求排查与修改方案

问题:JSON扁平化工具仅返回数组中最后一个用户的结果

我有一个包含多个用户的JSON结构,想通过Java代码将其扁平化,但遇到了一个问题:不管数组里有多少用户,代码始终只输出最后一个用户的扁平化结果。

输入JSON结构

{ 
  "users": [ 
    { 
      "displayName": "Sharad Dutta", 
      "givenName": "", 
      "surname": "", 
      "extension_user_type": "user", 
      "identities": [ 
        { 
          "signInType": "emailAddress", 
          "issuerAssignedId": "kkr007@gmail.com" 
        } 
      ], 
      "extension_timezone": "VET", 
      "extension_locale": "en-GB", 
      "extension_tenant": "EG12345" 
    }, 
    { 
      "displayName": "Sharad Dutta", 
      "givenName": "", 
      "surname": "", 
      "extension_user_type": "user", 
      "identities": [ 
        { 
          "signInType": "emailAddress", 
          "issuerAssignedId": "kkr007@gmail.com" 
        } 
      ], 
      "extension_timezone": "VET", 
      "extension_locale": "en-GB", 
      "extension_tenant": "EG12345" 
    } 
  ] 
}

期望的扁平化输出(示例)

{ 
  "extension_timezone": "VET", 
  "extension_tenant": "EG12345", 
  "extension_locale": "en-GB", 
  "signInType": "userName", 
  "displayName": "Wayne Rooney", 
  "surname": "Rooney", 
  "givenName": "Wayne", 
  "issuerAssignedId": "pdhongade007", 
  "extension_user_type": "user" 
}

问题代码

public class TestConvertor {
    static String userJsonAsString;
    public static void main(String[] args) throws JSONException {
        String userJsonFile = "C:\\Users\\Administrator\\Desktop\\jsonRes\\json_format_user_data_input_file.json";
        try {
            userJsonAsString = readFileAsAString(userJsonFile);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        JSONObject object = new JSONObject(userJsonAsString); // this is your input
        Map<String, Object> flatKeyValue = new HashMap<String, Object>();
        System.out.println("flatKeyValue : " + flatKeyValue);
        readValues(object, flatKeyValue);
        System.out.println(new JSONObject(flatKeyValue)); // this is flat
    }
    static void readValues(JSONObject object, Map<String, Object> json) throws JSONException {
        for (Iterator it = object.keys(); it.hasNext(); ) {
            String key = (String) it.next();
            Object next = object.get(key);
            readValue(json, key, next);
        }
    }
    static void readValue(Map<String, Object> json, String key, Object next) throws JSONException {
        if (next instanceof JSONArray) {
            JSONArray array = (JSONArray) next;
            for (int i = 0; i < array.length(); ++i) {
                readValue(json, key, array.opt(i));
            }
        } else if (next instanceof JSONObject) {
            readValues((JSONObject) next, json);
        } else {
            json.put(key, next);
        }
    }
    private static String readFileAsAString(String inputJsonFile) throws Exception {
        return new String(Files.readAllBytes(Paths.get(inputJsonFile)));
    }
}

问题原因分析

核心问题出在共享同一个Map对象处理数组中的所有元素。当遍历users数组时,每一个用户对象的扁平化键值对都会往同一个flatKeyValue Map里存,后面用户的键值对会直接覆盖前面用户的同名键(比如两个用户都有displayName,第二个的会覆盖第一个的),最后Map里就只剩下最后一个用户的所有键值对了。

另外,你的代码没有考虑数组元素的区分——如果要保留所有用户的扁平化结果,应该把每个用户的扁平化Map放到一个集合(比如List)里,而不是用单个Map来存储。

修改建议与修正代码

我们需要调整逻辑:当遇到users数组时,为每个用户创建独立的扁平化Map,然后把这些Map收集到一个List中,最终输出这个List的JSON(或者根据需求选择输出所有用户,还是允许用户指定索引)。

修正后的代码如下:

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class TestConvertor {
    static String userJsonAsString;

    public static void main(String[] args) throws JSONException {
        String userJsonFile = "C:\\Users\\Administrator\\Desktop\\jsonRes\\json_format_user_data_input_file.json";
        try {
            userJsonAsString = readFileAsAString(userJsonFile);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        JSONObject object = new JSONObject(userJsonAsString); // 输入JSON
        List<Map<String, Object>> allFlatUsers = new ArrayList<>();

        // 处理users数组
        JSONArray usersArray = object.getJSONArray("users");
        for (int i = 0; i < usersArray.length(); i++) {
            JSONObject userObj = usersArray.getJSONObject(i);
            Map<String, Object> flatUser = new HashMap<>();
            readValues(userObj, flatUser);
            allFlatUsers.add(flatUser);
        }

        // 输出所有扁平化后的用户
        System.out.println(new JSONArray(allFlatUsers));
        // 如果只需要第一个用户,直接取allFlatUsers.get(0)即可
        // System.out.println(new JSONObject(allFlatUsers.get(0)));
    }

    static void readValues(JSONObject object, Map<String, Object> json) throws JSONException {
        for (Iterator it = object.keys(); it.hasNext(); ) {
            String key = (String) it.next();
            Object next = object.get(key);
            readValue(json, key, next);
        }
    }

    static void readValue(Map<String, Object> json, String key, Object next) throws JSONException {
        if (next instanceof JSONArray) {
            JSONArray array = (JSONArray) next;
            // 处理内部数组(比如identities),这里直接遍历每个元素并扁平化
            for (int i = 0; i < array.length(); ++i) {
                readValue(json, key, array.opt(i));
            }
        } else if (next instanceof JSONObject) {
            readValues((JSONObject) next, json);
        } else {
            json.put(key, next);
        }
    }

    private static String readFileAsAString(String inputJsonFile) throws Exception {
        return new String(Files.readAllBytes(Paths.get(inputJsonFile)));
    }
}

代码说明

  1. 独立处理每个用户:遍历users数组时,为每个用户创建新的HashMap,避免键值对覆盖。
  2. 收集所有结果:用List<Map<String, Object>>存储所有用户的扁平化结果,最终可以输出为JSON数组。
  3. 保留原有扁平化逻辑:内部的readValues和readValue方法保持不变,继续处理单个用户对象的嵌套结构(比如identities数组)。

如果你只需要输出某个特定用户(比如第一个),直接从allFlatUsers中取出对应索引的Map即可。

内容的提问来源于stack exchange,提问作者horizon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:47:51