gpt4 book ai didi

json - 如何通过 Gson 获取过滤后的 JSON 节点?

转载 作者:行者123 更新时间:2023-12-03 15:37:26 24 4
gpt4 key购买 nike

我正在使用 Gson 来解析和编写 JSON 数据。

[{
"Source":"IN",
"Type":"PRD",
"Name":"ABC"
"IsActive":true
}, {
"Source":"IN",
"Type":"COB",
"Name":"XYZ"
"IsActive":true
}, {
"Source":"PRo",
"Type":"RPT",
"Name":"TEST"
"IsActive":true
}]

如何根据某些属性值获取 JSON 节点?例如,我想获取一个值为 Source 的节点。 = PRo , Type = RPTName = TEST .

我怎么能用 Gson 做到这一点?

最佳答案

正如我上面所说,Gson 不是一个查询库。但是这里至少有四种策略可以与 Gson 一起使用:

  • 使用内存策略
  • 使用 JSON 树模型
  • 使用动态映射
  • 使用静态映射
  • 使用流式策略

  • 以上各有其优点和缺点。对特定节点应用一些修改是一个微不足道的 filter-and-then-forEach 问题,并且可以很容易地通过命令式 for 解决。/ if或使用 Java 8 Stream API。

    JSON树模型

    JSON 树模型用于在内存中构建特定 JSON 文档的 JSON 表示。具有类似 DOM 的结构,您可以轻松地遍历和修改任何树叶。但是,它需要大量内存。

    try ( final Reader reader = getPackageResourceReader(Q43200432.class, "q43200432.json") ) {
    final JsonArray rows = jsonParser.parse(reader).getAsJsonArray();
    StreamSupport.stream(rows.spliterator(), false)
    .map(JsonElement::getAsJsonObject)
    .filter(jsonObject -> jsonObject.get("Source").getAsString().equals("PRo")
    && jsonObject.get("Type").getAsString().equals("RPT")
    && jsonObject.get("Name").getAsString().equals("TEST")
    )
    .forEach(jsonObject -> jsonObject.add("IsActive", new JsonPrimitive(false)));
    System.out.println(rows);
    }

    JSON 映射到 Map

    与上面类似,但行结构甚至没有与 Gson JSON 树模型 API 绑定(bind),因此值可以是字面上的任何类型。

    private static final Gson gson = new Gson();

    private static final Type rowListType = new TypeToken<List<Map<String, Object>>>() {
    }.getType();

    ...

    try ( final Reader reader = getPackageResourceReader(Q43200432.class, "q43200432.json") ) {
    final List<Map<String, Object>> rows = gson.fromJson(reader, rowListType);
    rows.stream()
    .filter(r -> r.get("Source").equals("PRo")
    && r.get("Type").equals("RPT")
    && r.get("Name").equals("TEST"))
    .forEach(r -> r.put("IsActive", false));
    System.out.println(gson.toJson(rows, rowListType));
    }

    JSON 映射到自定义映射(普通的旧 Java 对象)

    final class Row {

    @SerializedName("Source")
    String source;

    @SerializedName("Type")
    String type;

    @SerializedName("Name")
    String name;

    @SerializedName("IsActive")
    boolean isActive;

    }

    private static final Gson gson = new Gson();

    private static final Type rowListType = new TypeToken<List<Row>>() {
    }.getType();

    ...

    try ( final Reader reader = getPackageResourceReader(Q43200432.class, "q43200432.json") ) {
    final List<Row> rows = gson.fromJson(reader, rowListType);
    rows.stream()
    .filter(r -> "PRo".equals(r.source) && "RPT".equals(r.type) && "TEST".equals(r.name))
    .forEach(r -> r.isActive = false);
    System.out.println(gson.toJson(rows, rowListType));
    }

    流媒体

    流式处理允许逐个 token 读取 JSON token 并进行某种分析。由于流式传输不需要将整个文档存储在内存中,它甚至可以处理无限流,但它可能看起来有点难以使用。

    private static final Gson gson = new Gson();

    ...

    final TypeAdapter<JsonObject> jsonObjectTypeAdapter = gson.getAdapter(JsonObject.class);
    final Writer writer = new StringWriter();
    try ( final JsonReader jsonReader = new JsonReader(getPackageResourceReader(Q43200432.class, "q43200432.json"));
    final JsonWriter jsonWriter = new JsonWriter(writer) ) {
    jsonReader.beginArray();
    jsonWriter.beginArray();
    while ( jsonReader.hasNext() ) {
    final JsonObject jsonObject = jsonObjectTypeAdapter.read(jsonReader);
    if ( jsonObject.get("Source").getAsString().equals("PRo")
    && jsonObject.get("Type").getAsString().equals("RPT")
    && jsonObject.get("Name").getAsString().equals("TEST") ) {
    jsonObject.add("IsActive", new JsonPrimitive(false));
    }
    jsonObjectTypeAdapter.write(jsonWriter, jsonObject);
    }
    jsonReader.endArray();
    jsonWriter.endArray();
    }
    System.out.println(writer);

    上述所有四种策略都会产生以下输出:

    [{"Source":"IN","Type":"PRD","Name":"ABC","IsActive":true},{"Source":"IN","Type":"COB","Name":"XYZ","IsActive":true},{"Source":"PRo","Type":"RPT","Name":"TEST","IsActive":false}]



    请注意,位于 $[2].IsActive 的最后一个元素设置为 false .

    关于json - 如何通过 Gson 获取过滤后的 JSON 节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43200432/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com