使用Gson Java解析和获取嵌套的JSON对象。

huangapple go评论125阅读模式
英文:

Parsing and getting nested json objects using gson java

问题

我有这个JSON文件:

{
  "Update tree": {
    "average time": 0.01610115085649609,
    "best time": 0.003310859220941582,
    "count": 651,
    "success rate": 100,
    "worst time": 0.621779361692829
  },
  "Update renderables": {
    "average time": 0.1988377572034353,
    "best time": 0.0003510859220941582,
    "count": 649,
    "success rate": 100,
    "worst time": 12.8709652214104
  },
  "Before render": {
    "average time": 0.5206290903024032,
    "best time": 0.01522995241633128,
    "count": 188,
    "success rate": 100,
    "worst time": 81.06473259514415
  },
  "Rendering": {
    "average time": 4.425231035278629,
    "best time": 0.4979532268296139,
    "count": 214,
    "success rate": 100,
    "worst time": 71.34537426614806
  },
  "After render": {
    "average time": 0.06479598048728916,
    "best time": 0.0301288189105684,
    "count": 563,
    "success rate": 100,
    "worst time": 0.6413134310963844
  }
}

我想计算每个JSON对象中所有平均值的平均值,如何迭代JSON对象?

我试图获取所有平均值并将它们相加,然后计算它们的平均值。

编辑:

我有这个for循环,我想迭代每个对象(不仅获取其成员名称,而是实际迭代对象并获取值,然后将它们相加):

for (int i = 0; i < json.size(); i++) {
    sumAllAverages(json.getAsJsonObject());
}

private static void sumAllAverages(JsonObject asJsonObject) {
    sum += Float.parseFloat(asJsonObject.get("average time").toString());
}
英文:

I have this json file:

{
  &quot;Update tree&quot;: {
    &quot;average time&quot;: 0.01610115085649609,
    &quot;best time&quot;: 0.003310859220941582,
    &quot;count&quot;: 651,
    &quot;success rate&quot;: 100,
    &quot;worst time&quot;: 0.621779361692829
  },
  &quot;Update renderables&quot;: {
    &quot;average time&quot;: 0.1988377572034353,
    &quot;best time&quot;: 0.0003510859220941582,
    &quot;count&quot;: 649,
    &quot;success rate&quot;: 100,
    &quot;worst time&quot;: 12.8709652214104
  },
  &quot;Before render&quot;: {
    &quot;average time&quot;: 0.5206290903024032,
    &quot;best time&quot;: 0.01522995241633128,
    &quot;count&quot;: 188,
    &quot;success rate&quot;: 100,
    &quot;worst time&quot;: 81.06473259514415
  },
  &quot;Rendering&quot;: {
    &quot;average time&quot;: 4.425231035278629,
    &quot;best time&quot;: 0.4979532268296139,
    &quot;count&quot;: 214,
    &quot;success rate&quot;: 100,
    &quot;worst time&quot;: 71.34537426614806
  },
  &quot;After render&quot;: {
    &quot;average time&quot;: 0.06479598048728916,
    &quot;best time&quot;: 0.0301288189105684,
    &quot;count&quot;: 563,
    &quot;success rate&quot;: 100,
    &quot;worst time&quot;: 0.6413134310963844
  }
}

where I want to calculate the average of all avergaes in each json object how do I iterate through the json objects?

I am trying to get all avergaes values sum them up and calculate their average

EDIT:

I have this for loop which I want to iterate through each object (and not getting its member name but to actually iterate through the objects and get the values and then sum them up):

for(int i=0; i&lt;json.size(); i++){
            sumAllAverages(json.getAsJsonObject());
        }

private static void sumAllAverages(JsonObject asJsonObject) {
        sum += Float.parseFloat(asJsonObject.get(&quot;average time&quot;).toString());
    }

答案1

得分: 2

使用GSON,您只需将其反序列化为一个映射,如下所示:

Type type = new TypeToken<Map<String, Map<String, Double>>>() {}.getType();
Map<String, Map<String, Double>> map =
        new Gson().fromJson(getResourceStreamReader("file.json"), type);

_getResourceStreamReader("file.json")_ 只是一个从资源文件获取JSON的辅助方法。它可以是字符串或任何读取器。

要获取所有平均时间(例如):

Set<Double> averageTimes = map.values().stream()
    .map(v -> v.get("average time")).collect(Collectors.toSet());

要检查来自此映射的平均值,您可以执行以下操作:

averageTimes.forEach(averageTime -> System.out.println(averageTime));

这将产生:

> 0.01610115085649609
0.1988377572034353
0.5206290903024032
4.425231035278629
0.06479598048728916

此外,您可以使用reduce来累加所有值并获得总平均时间:

Double totalAverageTime = averageTimes.stream()
            .reduce((a, b) -> a + b).orElse(0D) / averageTimes.size();

检查它:

System.out.println(totalAverageTime);

您将会看到:

> 1.0451190028256505

注意:所有这些计算甚至可以在一个lambda中完成,但为了清晰起见并使其更易于理解,我已将这些步骤分开了。

英文:

With GSON you can just deserialize this to a map like:

Type type = new TypeToken&lt;Map&lt;String, Map&lt;String, Double&gt;&gt;&gt;() {}.getType();
Map&lt;String, Map&lt;String, Double&gt;&gt; map =
        new Gson().fromJson(getResourceStreamReader(&quot;file.json&quot;), type);

getResourceStreamReader("file.json") is just a helper method to get your JSON from a resource file. It can be String or any reader.

To have all the average times (for example):

Set&lt;Double&gt; averageTimes = map.values().stream()
    .map(v -&gt; v.get(&quot;average time&quot;)).collect(Collectors.toSet());

To inspect the averages from this map you can for example do this:

averageTimes.forEach(averageTime -&gt; System.out.println(averageTime));

This produces:

> 0.01610115085649609
0.1988377572034353
0.5206290903024032
4.425231035278629
0.06479598048728916

Further you can use reduce to sum all the values and get the total average time;

Double totalAverageTime = averageTimes.stream()
            .reduce((a, b) -&gt; a + b).orElse(0D) / averageTimes.size();

Inspect it:

System.out.println(totalAverageTime);

and you will see:

> 1.0451190028256505

Note: all this calculation may be done with yet fewer lines even in one lambda but for clarity and making it easier to follow I have splitted the phases.

答案2

得分: -1

这是我在Jackson中的做法,gson应该是相似的。

JsonNode time_Data;
try {
    time_Data = new ObjectMapper().readTree(jsonTimes); // **将文件作为字符串传入此处
    double sum = 0.0;
    if(time_Data != null) {
        for (final JsonNode valuesPacket : time_Data) {
            sum += Double.parseDouble(valuesPacket.get("average time").asText());
        }
    }
    System.out.println("sum is :" + sum);
} catch (JsonProcessingException e) {
    // TODO: 自动生成的 catch 块
    e.printStackTrace();
} catch (IOException e) {
    // TODO: 自动生成的 catch 块
    e.printStackTrace();
}
英文:

This is how I do it in Jackson, gson should be fairly similar.

JsonNode time_Data;
    try {
      time_Data = new ObjectMapper().readTree(jsonTimes); // **this is your file as a string
      double sum = 0.0;
      if(time_Data!= null) {
        for (final JsonNode valuesPacket : time_Data) {
          sum += Double.parseDouble(valuesPacket.get(&quot;average time&quot;).asText());
        }
      }
      System.out.println(&quot;sum is :&quot;+sum);
    } catch (JsonProcessingException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

huangapple
  • 本文由 发表于 2020年7月23日 15:35:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63049141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定