Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用GSON迭代JSON数组并从中提取每个JSON对象?_Java_Json_Gson_Arrays_Jsonobject - Fatal编程技术网

Java 如何使用GSON迭代JSON数组并从中提取每个JSON对象?

Java 如何使用GSON迭代JSON数组并从中提取每个JSON对象?,java,json,gson,arrays,jsonobject,Java,Json,Gson,Arrays,Jsonobject,下面是我从服务API调用得到的JSON字符串。为了便于理解,我将其缩短为只有三个reportRecords。一般来说,它可能有约500条reportRecords {    "aggRecords": {       "reportRecords": [          {             "min": 0,             "max": 12,             "avg": 0.3699187,             "count": 246,           

下面是我从服务API调用得到的JSON字符串。为了便于理解,我将其缩短为只有三个
reportRecords
。一般来说,它可能有约500条
reportRecords

{
   "aggRecords": {
      "reportRecords": [
         {
            "min": 0,
            "max": 12,
            "avg": 0.3699187,
            "count": 246,
            "sumSq": 571,
            "stddev": 1.4779372,
            "median": 0,
            "percentileMap": {
               "95": 4
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "PostProcessing",
               "Type": "PostProcessing"
            },
            "value": 91
         },
         {
            "min": 0,
            "max": 23,
            "avg": 2.3991289E-4,
            "count": 1463031,
            "sumSq": 3071,
            "stddev": 0.045814946,
            "median": 0,
            "percentileMap": {
               "95": 0
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "ResourceContext",
               "Type": "ResourceContext"
            },
            "value": 351
         },
         {
            "min": 0,
            "max": 1209,
            "avg": 1.9203402,
            "count": 7344636,
            "sumSq": 71832774,
            "stddev": 2.4683187,
            "median": 2,
            "percentileMap": {
               "95": 4
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "Client::Sync",
               "Type": "Client::Sync"
            },
            "value": 14104200
         }
      ]
   },
   "minRecordsMap": {}
}
现在,从上面的JSON响应中,我需要提取
reportRecords
,它的
Name
Client::Sync
。也就是说,我只需要从上面的JSON响应中提取下面的
reportRecords

         {
            "min": 0,
            "max": 1209,
            "avg": 1.9203402,
            "count": 7344636,
            "sumSq": 71832774,
            "stddev": 2.4683187,
            "median": 2,
            "percentileMap": {
               "95": 4
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "Client::Sync",
               "Type": "Client::Sync"
            },
            "value": 14104200
         }
现在我需要为
Client::Sync
将上面的
reportRecords
解析到下面的对象-

public class DataMetrics {

    private String pool;
    private String name;
    private String type;
    private String env;
    private String metricName;
    private String percentile;
    private String median;
    private String stdDev;
    private String sumSq;
    private String count;
    private String avg;
    private String max;
    private String min;

    // getters and setters here
}
上面的变量,映射如下-

pool is titan
name is Client::Sync 
type is Client::Sync
env is dev
metricNname is TransactionDuration
95th  percentile is 4
median is 2
stdDev is 2.4683187 
sumSq is 71832774 
count is 7344636 
avg is 1.9203402
max is 1209
min is 0
我在这里使用GSON库,下面是我迄今为止尝试过的-

private static RestTemplate restTemplate = new RestTemplate();

public static void main(String[] args) {

    String jsonLine = restTemplate.getForObject("some_url", String.class);
    System.out.println(jsonLine); // here jsonLine will give me above big JSON String

    JsonElement jelement = new JsonParser().parse(jsonLine);
    JsonObject  jobject = jelement.getAsJsonObject();
    jobject = jobject.getAsJsonObject("aggRecords");
    JsonArray jarray = jobject.getAsJsonArray("reportRecords");

    // now how do I iterate JsonArray and get each JSON object
    // and then check "name" property of each object, if "Client::Sync" found, read that object for all properties
    // and set it using setters.

}

现在我无法理解如何迭代JsonArray并从中提取每个JSON对象?

您可能需要解析所有对象,然后过滤您感兴趣的对象

获得jArray后,请尝试:

//get json array from json string
JsonArray jarray = jobject.getAsJsonArray("reportRecords");

//get a list of reportRecords using Gson
Gson mGson = new Gson();
Type listType = new TypeToken<List<DataMetrics>>(){}.getType();
List<DataMetrics> dataMetricsList = mGson.fromJson(reportRecordsJsonArray, listType);

//Filter only the ones with a specific name
List<DataMetrics> dataMetricsFilteredList = dataMetricsList.stream().filter(dataMetric -> dateMetric.getName.equals("Client::Sync"));
//从json字符串获取json数组
JsonArray jarray=jobject.getAsJsonArray(“报告记录”);
//使用Gson获取reportRecords列表
Gson mGson=新的Gson();
类型listType=newTypeToken(){}.getType();
List dataMetricsList=mGson.fromJson(reportRecordsJShonaray,listType);
//仅筛选具有特定名称的
List dataMetricsFilteredList=dataMetricsList.stream().filter(dataMetric->dateMetric.getName.equals(“Client::Sync”);

我没有试过,但它可能有用

 public void getFromJson(JSONObject json)
         {
             JSONArray jarray = (JSONArray) json.get("reportRecords");
             List<DataMetrics> myList = new ArrayList();
             for(int i = 0; i < jarray.size(); i++)
             {
                 myList.add((DataMetrics) getClassFromJsonObject((JSONObject) jarray.get(i),
 DataMetrics.class));
             }
         }

因此,记录中有JsonArray对象,下面是获取函数对象的方法:

Type type = new TypeToken<List<DataMetrics>>() {}.getType();
List<DataMetrics> records = gson.fromJson(jsonArrayThatYouHave, type);
Type Type=new-TypeToken(){}.getType();
List records=gson.fromJson(jsonArrayThatYouHave,type);
然后遍历对象并过滤所需的对象。 在java 8中,可以执行以下操作:

List<DataMetrics> result = records.stream().filter(record -> record.name.equals("Client::Sync")).collect(toList());
List result=records.stream().filter(record->record.name.equals(“Client::Sync”)).collect(toList());
这种方法是转换所有对象并在之后进行迭代,如果这部分代码确实是性能关键的,那么您仍然可以通过json进行迭代,并仅转换必要的对象(但我怀疑这实际上会比上面描述的更快)

无论如何,这是更易于维护和理解的代码

更新:

java 7的相同功能将是:

List<DataMetrics> result = new LinkedList<>();

for(DataMetrics record : records){
   if(record.name.equals("Client::Sync")){
      result.add(record);
   }
}
List result=newlinkedlist();
对于(DataMetrics记录:记录){
if(record.name.equals(“Client::Sync”)){
结果.添加(记录);
}
}

或者,如果您想迭代json并只解析所需的json,您可以执行以下操作:

Type type = new TypeToken<List<DataMetrics>>() {}.getType();

for(JsonElement elem : jsonArrayThatYouHave) {
   if (elem.getAsJsonObject().get("name").getAsString().equals("Client::Sync")) {
      result.add(gson.fromJson(elem, type));
   }
}
Type Type=new-TypeToken(){}.getType();
for(JsonElement元素:jsonArrayThatYouHave){
if(elem.getAsJsonObject().get(“name”).getAsString().equals(“Client::Sync”)){
add(gson.fromJson(elem,type));
}
}

但我认为这实际上并不比第一个更快,因为在这两种情况下,您都是使用解析器将json转换为java函数对象,并获得JsonArray或其他任何东西。考虑到两者都是Google LIB,我假设使用gson从JsonObject解析到某个特定类型比从字符串(原始json)解析到同一特定类型要快得多…

@hexin我正在使用gson,我猜上面的示例不使用gson。谢谢Vach。在Java7中我将如何做到这一点?我现在正在使用Java7。谢谢你的帮助。我试过了,但不知怎么的,大多数字段都是空的,比如百分位、名称、类型、最小值等,但有些字段有数据。您是否看到任何错误?您只需要与json中相同的类属性名称(如果不想更改,请使用@Qualifier注释指定它)
Type type = new TypeToken<List<DataMetrics>>() {}.getType();

for(JsonElement elem : jsonArrayThatYouHave) {
   if (elem.getAsJsonObject().get("name").getAsString().equals("Client::Sync")) {
      result.add(gson.fromJson(elem, type));
   }
}