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

如何在C#或Java中将特定JSON结构解析为对象数组?

问题还原

原JSON结构(示例):

{
  "ASDAS": {
    "g": 123,
    "f": {
      "field1": "value1",
      "field2": 456
    }
  },
  "XYZ": {
    "g": 789,
    "f": {
      "field1": "value2",
      "field2": 0
    }
  }
}

期望转换后的对象数组结构:

[
  {
    "name": "ASDAS",
    "g": 123,
    "f": {
      "field1": "value1",
      "field2": 456
    }
  },
  {
    "name": "XYZ",
    "g": 789,
    "f": {
      "field1": "value2",
      "field2": 0
    }
  }
]
C# 实现方案

针对大文件场景,推荐使用流式解析减少内存开销,以下提供两种主流序列化库的实现:

1. 使用System.Text.Json(.NET Core/.NET 5+ 内置)

首先定义对应实体类:

// 对应原JSON中的f结构体
public class FStruct
{
    // 根据实际字段调整,字段名需与JSON一致,或用[JsonPropertyName]指定映射
    public string Field1 { get; set; }
    public int Field2 { get; set; }
}

// 目标数组的元素类
public class TargetItem
{
    public string Name { get; set; }
    public int G { get; set; }
    public FStruct F { get; set; }
}

流式解析代码:

using System.Text.Json;
using System.Collections.Generic;
using System.IO;

public List<TargetItem> ParseLargeJson(string filePath)
{
    var targetList = new List<TargetItem>();
    
    // 流式读取文件,避免一次性加载整个JSON到内存
    using var stream = File.OpenRead(filePath);
    using var doc = JsonDocument.Parse(stream, new JsonDocumentOptions { AllowTrailingCommas = true });
    
    // 遍历顶级键值对
    foreach (var property in doc.RootElement.EnumerateObject())
    {
        var item = new TargetItem
        {
            Name = property.Name,
            G = property.Value.GetProperty("g").GetInt32(),
            F = property.Value.GetProperty("f").Deserialize<FStruct>()
        };
        targetList.Add(item);
    }
    
    return targetList;
}

2. 使用Newtonsoft.Json(Json.NET)

实体类与上述一致,解析代码:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.IO;

public List<TargetItem> ParseLargeJsonWithNewtonsoft(string filePath)
{
    var targetList = new List<TargetItem>();
    
    using var reader = new JsonTextReader(new StreamReader(filePath));
    var jsonDict = JsonSerializer.Deserialize<Dictionary<string, JObject>>(reader);
    
    foreach (var kvp in jsonDict)
    {
        var item = new TargetItem
        {
            Name = kvp.Key,
            G = kvp.Value["g"].Value<int>(),
            F = kvp.Value["f"].ToObject<FStruct>()
        };
        targetList.Add(item);
    }
    
    return targetList;
}
Java 实现方案

同样针对大文件场景,推荐Jackson的流式API,以下是两种库的实现:

1. 使用Jackson(主流高性能序列化库)

定义实体类:

import com.fasterxml.jackson.annotation.JsonProperty;

// 对应原JSON中的f结构体
public class FStruct {
    @JsonProperty("field1")
    private String field1;
    @JsonProperty("field2")
    private int field2;
    
    // Getter和Setter方法
    public String getField1() { return field1; }
    public void setField1(String field1) { this.field1 = field1; }
    public int getField2() { return field2; }
    public void setField2(int field2) { this.field2 = field2; }
}

// 目标数组的元素类
public class TargetItem {
    private String name;
    private int g;
    private FStruct f;
    
    // Getter和Setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getG() { return g; }
    public void setG(int g) { this.g = g; }
    public FStruct getF() { return f; }
    public void setF(FStruct f) { this.f = f; }
}

流式解析代码:

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class JsonParserUtil {
    public static List<TargetItem> parseLargeJson(String filePath) throws Exception {
        List<TargetItem> targetList = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        JsonFactory factory = mapper.getFactory();
        
        // 流式解析,逐token处理
        try (JsonParser parser = factory.createParser(new File(filePath))) {
            // 跳过JSON开头的{
            parser.nextToken();
            
            while (parser.nextToken() != JsonToken.END_OBJECT) {
                String key = parser.getCurrentName();
                // 进入当前键对应的值对象
                parser.nextToken();
                
                TargetItem item = new TargetItem();
                item.setName(key);
                
                // 遍历值对象内的字段
                while (parser.nextToken() != JsonToken.END_OBJECT) {
                    String fieldName = parser.getCurrentName();
                    parser.nextToken();
                    
                    if ("g".equals(fieldName)) {
                        item.setG(parser.getIntValue());
                    } else if ("f".equals(fieldName)) {
                        // 反序列化f结构体
                        FStruct f = mapper.readValue(parser, FStruct.class);
                        item.setF(f);
                    }
                }
                
                targetList.add(item);
            }
        }
        
        return targetList;
    }
}

2. 使用Gson

实体类与上述一致,解析代码:

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class GsonParserUtil {
    public static List<TargetItem> parseLargeJson(String filePath) throws Exception {
        List<TargetItem> targetList = new ArrayList<>();
        Gson gson = new Gson();
        
        try (FileReader reader = new FileReader(filePath)) {
            JsonObject jsonObj = JsonParser.parseReader(reader).getAsJsonObject();
            
            // 遍历顶级键值对
            for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
                JsonObject valueObj = entry.getValue().getAsJsonObject();
                
                TargetItem item = new TargetItem();
                item.setName(entry.getKey());
                item.setG(valueObj.get("g").getAsInt());
                item.setF(gson.fromJson(valueObj.get("f"), FStruct.class));
                
                targetList.add(item);
            }
        }
        
        return targetList;
    }
}
通用解析思路
  1. 核心逻辑:遍历JSON的顶级键值对,将每个键映射为目标对象的name字段,提取值对象中的g字段,将f字段反序列化为对应结构体,最后收集所有对象到数组/列表。
  2. 大文件优化:优先使用流式解析API,避免一次性加载整个JSON到内存,降低内存占用,提升处理效率。
  3. 字段适配:根据实际JSON中f的字段调整实体类属性,若字段名不匹配,可通过序列化特性(如C#的[JsonPropertyName]、Java的@JsonProperty)指定映射关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:32:56