我有一个简单的Java
应用程序,它需要遍历一个大型JSON
数组(包含约2万个项目),并且在每个数组中,我解析一个子数组。每个项目看起来像这样:
{"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
}
有没有一种优化方法?
答案 0 :(得分:1)
您应该减少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"));
}
}
}
答案 1 :(得分:0)
知道了。感谢Erwin,我可以将整个JSON一次解析成HASHMap
,就像这样:
ArrayList<HashMap> json= JsonPath.read(response, "$.result");
然后我们可以简单地调用get(i)
来访问循环中的特定项目:
double start_time = (double) json.get(i).get("startTime");