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

如何用Java 8 Lambda与Stream处理含不同键的JSONObject及JSONArray

用Java 8 Stream + Lambda重构JSON遍历代码

需求说明

刚接触Java 8 Lambda,希望把遍历JSONArray生成指定字段JSONObject的for循环代码,改成用Lambda和Stream实现。具体需求是:接收包含学生信息的JSONArray,生成两个JSONObject——一个以language为键、name为值,另一个以language为键、section为值。

示例输入

"students": [
    {
        "name": "tom",
        "section": "A",
        "language": "english"
    },
    {
        "name": "john",
        "section": "B",
        "language": "dutch"
    },
    {
        "name": "sam",
        "section": "C",
        "language": "spanish"
    }
]

预期输出

nameJson : {"english":"tom","dutch":"john","spanish":"sam"}
sectionJson: {"english":"A","dutch":"B","spanish":"C"}

现有for循环实现

JSONArray notification = json.optJSONArray("studentData");
JSONObject nameJson = new JSONObject();
JSONObject sectionJson = new JSONObject();
for (int i = 0; i < notification.length(); i++) {
    nameJson.put(
        notification.getJSONObject(i).get("language").toString(),
        notification.getJSONObject(i).get("name").toString()
    );
    sectionJson.put(
        notification.getJSONObject(i).get("language").toString(),
        notification.getJSONObject(i).getString("section").toString()
    );
}

Stream + Lambda重构方案

由于JSONArray本身不支持直接转成Stream,我们可以通过索引流遍历元素,结合Collectors.toMap收集键值对,最后用JSONObject的Map构造器生成目标对象。

基础实现

JSONArray notification = json.optJSONArray("studentData");

// 生成nameJson
JSONObject nameJson = new JSONObject(
    IntStream.range(0, notification.length())
             .mapToObj(notification::getJSONObject)
             .collect(Collectors.toMap(
                 obj -> obj.getString("language"),
                 obj -> obj.getString("name")
             ))
);

// 生成sectionJson
JSONObject sectionJson = new JSONObject(
    IntStream.range(0, notification.length())
             .mapToObj(notification::getJSONObject)
             .collect(Collectors.toMap(
                 obj -> obj.getString("language"),
                 obj -> obj.getString("section")
             ))
);

优化复用版

如果需要多次转换不同字段,可以抽取通用方法减少重复代码:

// 通用转换方法
private static JSONObject convertToJSON(JSONArray array, 
                                       Function<JSONObject, String> keyExtractor, 
                                       Function<JSONObject, String> valueExtractor) {
    return new JSONObject(
        IntStream.range(0, array.length())
                 .mapToObj(array::getJSONObject)
                 .collect(Collectors.toMap(keyExtractor, valueExtractor))
    );
}

// 调用示例
JSONArray notification = json.optJSONArray("studentData");
JSONObject nameJson = convertToJSON(notification, 
                                    obj -> obj.getString("language"), 
                                    obj -> obj.getString("name"));
JSONObject sectionJson = convertToJSON(notification, 
                                       obj -> obj.getString("language"), 
                                       obj -> obj.getString("section"));

代码说明

  1. IntStream.range(0, notification.length()):生成从0到数组长度-1的索引流,模拟for循环的索引遍历逻辑
  2. mapToObj(notification::getJSONObject):将每个索引转换为对应的JSONObject对象
  3. Collectors.toMap(...):把每个JSONObject的指定字段作为键值对,收集成Map<String, String>
  4. new JSONObject(Map):利用JSONObject的构造器直接将Map转换为目标JSON对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:30:26