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

如何在Java 8中遍历包含JSONObject与JSONArray的JSONArray

解决混合JSONObject和JSONArray的JSONArray遍历问题(Java 8实现)

首先,你之前遇到的MismatchedInputException是因为顶层JSON数组里同时包含单个对象和子数组,直接用Jackson把整个数组反序列化成List<PojoClass>肯定行不通——Jackson没法自动识别这种混合结构,它期望所有元素都是PojoClass对应的对象,结果遇到数组节点就报错了。

你的普通for循环思路是对的,但有个小bug:内层循环里你错误用了jsonArrayList.optJSONObject(j),应该是jsonArrayInner.optJSONObject(j),不然会取到顶层数组的元素而非子数组的。不过既然要Java 8的实现,我们可以用流式API结合Jackson的JsonNode来更优雅地解决这个问题。

前提准备

首先确保你的PojoClass和JSON结构完全对应,比如嵌套的Value1_tim需要一个内部类或者单独的类:

public class PojoClass {
    private String Key1;
    private String Key2;
    private String Key3;
    private TimeValue Value1_tim;

    // 生成getter、setter、无参构造器

    public static class TimeValue {
        private int amVal;
        private String pmVal;

        // 生成getter、setter、无参构造器
    }
}

Java 8流式实现代码

我们用Jackson的JsonNode来灵活处理混合类型的JSON节点,配合流式API来遍历和收集结果:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

// 初始化ObjectMapper(建议全局单例)
ObjectMapper objectMapper = new ObjectMapper();

// 把JSON响应解析成顶层的ArrayNode
ArrayNode topLevelArray = (ArrayNode) objectMapper.readTree(jsonResponse);

// 流式遍历并收集所有PojoClass实例
List<PojoClass> pojoClassList = topLevelArray.stream()
    .flatMap(node -> {
        if (node.isObject()) {
            // 单个JSONObject节点:转成单元素流
            try {
                return Stream.of(objectMapper.treeToValue(node, PojoClass.class));
            } catch (Exception e) {
                throw new RuntimeException("反序列化单个对象失败", e);
            }
        } else if (node.isArray()) {
            // JSONArray节点:遍历内部的每个对象节点,转成流
            return ((ArrayNode) node).stream()
                .filter(JsonNode::isObject) // 确保只处理对象节点,避免非对象类型
                .map(innerNode -> {
                    try {
                        return objectMapper.treeToValue(innerNode, PojoClass.class);
                    } catch (Exception e) {
                        throw new RuntimeException("反序列化子数组对象失败", e);
                    }
                });
        } else {
            // 处理其他非对象/数组的节点(比如字符串、数字),这里直接忽略
            return Stream.empty();
        }
    })
    .collect(Collectors.toList());

代码解释

  1. 用readTree解析JSON:这个方法会把JSON转换成JsonNode树结构,能灵活处理各种JSON类型(对象、数组、基本类型),比org.json的JSONArray更适合和Jackson配合使用。
  2. flatMap合并流:flatMap的作用是把每个节点对应的流合并成一个大的流——单个对象转成单元素流,子数组转成内部对象的流,最终所有PojoClass实例都在同一个流里。
  3. treeToValue高效反序列化:直接把JsonNode转换成PojoClass,比先转成字符串再反序列化更高效,也避免了字符串转换的额外开销。
  4. 异常处理:这里用RuntimeException包裹反序列化异常,实际项目中你可以根据需求自定义异常类型,或者添加更细致的错误处理逻辑。

为什么不用org.json的API?

org.json的JSONArray和JSONObject更偏向于底层的JSON操作,而Jackson的JsonNode和ObjectMapper结合得更紧密,处理混合类型的JSON结构时代码更简洁,也更符合Java 8的流式编程风格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:01:34