HOWTO · Java

在 Java 中处理 JSON 数组

本文讨论 JSON 框架、其结构、数据类型及其在 Java 中的使用。

本页内容

要在 Java 中读取文件里的 JSON 数组,可以在项目中添加 JSON.simple 这类 JSON 解析器,解析文件后遍历得到的数组。Java 标准库不包含通用的 JSON 解析器。JSON.simple 是外部依赖,因此需要通过项目使用的构建工具或依赖管理器添加。

JSON.simple 有过多个发行版本和 API 系列。下面的示例使用 org.json.simple API 系列;使用前,请先选择一个版本,并查阅该版本的文档,确认依赖坐标、解析器 API 和值类型。本文不假定具体版本或构建工具。如果所选版本使用不同的包或方法签名,请根据该版本的文档调整示例,不要照搬不相关的依赖声明。

在 Java 中处理 JSON 数组

JSON(JavaScript Object Notation,JavaScript 对象表示法)使用对象、数组、字符串、数字、布尔值和 null 表示数据。Java 代码需要借助解析器将 JSON 文本转换为可处理的值。JSON.simple 是完成这一步的一种选择。

数组是用方括号括起来的有序序列。对象是用花括号括起来、由带名称的值组成的集合。数组和对象可以嵌套,因此文件可以从一个数组开始,其中的元素是对象,而每个对象又包含其他数组或对象。

Java 中的 JSON 对象和 JSON 数组

对象通过字符串键存储值,每个键和值之间用冒号分隔,各项之间用逗号分隔。数组按位置存储值,各项之间也用逗号分隔。例如,内联 JSON 值 [1, "abc", {"name":"xyz"}] 是一个包含数字、字符串和对象的数组。该对象有一个 name 键,其值为字符串。

示例文件的顶层是一个数组,其中只有一个对象。该对象包含一个字符串、一个数字、两个嵌套数组和一个嵌套对象:

[{"name":"MMN","roll":24,"marks":[91,95,97,97,94],"parents":{"name":"IMT","mobile":"1234567890"},"hobbies":["sports","reading","music"],"others":["A",1]}]

提取值时,数据结构很重要:读取 name、roll 或 parents 的代码,默认这些键存在且对应预期的 JSON 类型。如果输入来自你无法控制的来源,请先验证每个值,再将其当作特定的 Java 类型处理。

使用 JSON.simple 在 Java 中从文件读取 JSON 数组

通过项目的依赖管理器添加 JSON.simple。请使用所选确切版本文档中列出的构件坐标;由于本文没有指定具体版本或构建工具,因此不提供坐标。org.json.simple 包系列属于外部依赖;如果运行环境只有 Java,且类路径中没有匹配的库,其导入和解析器调用就无法运行。

对于使用兼容版本 JSON.simple 的项目,解析步骤的概念形式是 new JSONParser().parse(reader)。请查阅该版本的文档,确认准确的解析器 API 和返回的集合类型。下面的示例重点展示后续步骤:解析器生成数据后,如何遍历 Java 集合结构。示例中的值与上面的样例文件一致,并且只使用 Java 标准库中的集合,因此可以独立运行。

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JSONArrayTraversal {
  public static void main(String[] args) {
    Map<String, Object> parents = new LinkedHashMap<>();
    parents.put("name", "IMT");
    parents.put("mobile", "1234567890");

    Map<String, Object> record = new LinkedHashMap<>();
    record.put("name", "MMN");
    record.put("roll", 24);
    record.put("marks", Arrays.asList(91, 95, 97, 97, 94));
    record.put("parents", parents);
    record.put("hobbies", Arrays.asList("sports", "reading", "music"));
    record.put("others", Arrays.asList("A", 1));
    List<Map<String, Object>> records = Arrays.asList(record);

    for (Map<String, Object> item : records) {
      System.out.println("Name: " + item.get("name"));
      System.out.println("Roll: " + item.get("roll"));
      System.out.println("Marks: " + item.get("marks"));
      System.out.println("Hobbies: " + item.get("hobbies"));
      Map<?, ?> parent = (Map<?, ?>) item.get("parents");
      System.out.println("Parent's Name: " + parent.get("name")
          + ", Mobile: " + parent.get("mobile"));
      System.out.println("Others: " + item.get("others"));
    }
  }
}
Name: MMN
Roll: 24
Marks: [91, 95, 97, 97, 94]
Hobbies: [sports, reading, music]
Parent's Name: IMT, Mobile: 1234567890
Others: [A, 1]

在应用程序中,将所选 JSON.simple 解析器返回的值传给遍历代码,并根据该版本的集合类型调整代码。这里的 records 代表解析得到的顶层数组。类型转换和字段查找依赖于样例的数据结构;如果输入可能变化,请先验证每个数组元素和字段,再依据其类型进行处理。解析期间应保持读取器打开,并在解析结束后关闭,即使解析失败也要关闭。请根据所选版本文档说明的行为以及应用程序的需求处理文件访问和解析失败。将此遍历逻辑连接到文件输入时,请提供一个在当前环境中确实存在且可读取的路径。

结论

JSON 数组是有序序列,而 JSON 对象通过键关联带名称的值。要在 Java 中从文件读取 JSON 数组,可以使用 JSON.simple 等外部解析器,在项目中添加所选版本对应的依赖,然后按照输入的数据结构遍历解析结果。在依赖类型转换或数值转换之前,请确认所选版本的 API 和数值类型。