Итерация по большому массиву JSON с JSONPath - PullRequest
1 голос
/ 27 марта 2019

У меня есть простое приложение Java, которое должно пройти через большой массив JSON (около 20 тыс. Элементов), и в каждом массиве я анализирую подмассив.Каждый элемент выглядит следующим образом:

{"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
}

Есть ли способ оптимизировать его?

Ответы [ 2 ]

1 голос
/ 27 марта 2019

Вы должны минимизировать количество операций read. При первом сканировании всего файла, а затем при частичном сканировании n раз. Чтение с диска происходит медленнее, чем из памяти: числа задержек, которые должен знать каждый программист , поэтому вы должны загрузить файл в память один раз, а затем выполнить итерации по элементам. Также из 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"));
        }
    }
}
0 голосов
/ 27 марта 2019

Понял.Благодаря Эрвину я могу сразу проанализировать весь JSON в HASHMap просто так:

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

А затем мы можем просто позвонить get(i) для доступа к определенному элементу в цикле:

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