【问题标题】:Iterate over a large JSON Array with JSONPath使用 JSONPath 遍历大型 JSON 数组
【发布时间】:2019-03-26 21:32:28
【问题描述】:

我有一个简单的 Java 应用程序,它需要遍历一个大的 JSON 数组(大约有 20K 项),并且在每个数组中,我解析一个子数组。每个项目如下所示:

{"index":0,"f1":[2,16,16,16,16,16,32,16],"f2":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"startTime":0.0}

我正在使用JSONPath 来迭代每个项目。我所做的是首先读取长度,然后简单地遍历整个数组。但它非常慢(例如,每秒 1 个项目)。

int length = JsonPath.read(response, "$.result.length()");
for (int i = 0; i < length; i++) {
    double start_time = JsonPath.read(response, "$.result["+i+"].startTime");
    ArrayList<Integer> f1= JsonPath.read(response, "$.result["+i+"].f1");
    //...other things
}

有办法优化吗?

【问题讨论】:

  • 是的 - 首先将您的 JSON 文件解析为数据结构一次,然后您就可以访问该数据结构。您当前所做的是每次从中检索值时解析 JSON,正如您所注意到的,这非常非常慢。见stackoverflow.com/questions/2591098/how-to-parse-json-in-java
  • 你能在JSONPath上用sn-ps详细说明吗?

标签: java arrays json parsing jsonpath


【解决方案1】:

知道了。感谢 Erwin,我可以一次将整个 JSON 解析为 HASHMap,就像这样:

ArrayList<HashMap> json= JsonPath.read(response, "$.result");

然后我们可以简单地调用get(i) 来访问循环中的特定项目:

double start_time = (double) json.get(i).get("startTime");

【讨论】:

    【解决方案2】:

    您应该尽量减少read 操作的数量。第一次扫描整个文件,然后部分扫描n 次文件。从磁盘读取比从内存慢:Latency Numbers Every Programmer Should Know,因此您应该将文件加载到内存一次,然后迭代项目。另外,来自JsonPath 文档:

    如果您只想阅读一次,这是可以的。如果您需要阅读 其他路径也是如此,这不是要走的路,因为文档将 每次调用 JsonPath.read(...) 时都会被解析。为了避免问题 你可以先解析json。

    String json = "...";
    Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
    
    List<Integer> f10 = JsonPath.read(document, "$.result[0].f1");
    List<Integer> f11 = JsonPath.read(document, "$.result[1].f1");
    

    您可以改进您的JsonPath$.result,并通过以下方式仅阅读您需要的内容:$.result..['f1','startTime']

    仅加载必填字段的示例应用:

    import com.jayway.jsonpath.JsonPath;
    
    import java.io.File;
    import java.util.List;
    import java.util.Map;
    
    public class JsonPathApp {
    
        public static void main(String[] args) throws Exception {
            File jsonFile = new File("./resource/test.json").getAbsoluteFile();
            List<Object> array = JsonPath.read(jsonFile, "$.result..['f1','startTime']");
            for (Object item : array) {
                Map<String, Object> map = (Map<String, Object>) item;
                System.out.println(map.get("f1"));
                System.out.println(map.get("startTime"));
            }
        }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 2011-02-05
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多