从LinkedHashMap中检索值

我有一个看起来像这样的对象:

{ /test1: { get: { tags: [ "restcalls" ] } }, /test2: { put: { tags: [ "restcalls" ] } } } 

我正在检索上面这样的对象:

 HashMap json = new ObjectMapper().readValue(str, HashMap.class); 

但是,检索tags并用其他关键字替换它们的最佳方法是"my rest calls" 。 请注意,get,put也可以是任何其他变量名,所以它的动态但标签总是在get,put下。

您已经选择Jackson作为您的Java-JSON库( 我可以说这是一个不错的选择 ),因此您手头的问题是如何使用Jackson以最佳方式遍历和更新JSON,但是那些甚至决定使用哪种Java -JSON库可以在这里阅读,它比较了下面提到的7个Java-JSON库。 以下是链接的结论摘录:

总而言之,如果您知道在应用程序中只使用少量数据并且希望以JSON格式存储或读取它,则应考虑使用Flexjson或Gson 。 如果您要使用大量数据并希望以JSON格式存储或读取它,则应考虑使用Jackson或JSON-lib

  • jackson
  • 谷歌,GSON
  • JSON-LIB
  • Flexjson
  • JSON-IO
  • genson
  • JSONiJ

jackson

最重要的是要知道Jackson提供了三种处理JSON的替代方法( 在这里阅读更多),因此应该根据具体要求明智地选择合适的方法。

  1. Streaming API又名“Incremental parsing / generation” ):它将JSON内容作为离散事件进行读写。 最佳用例:迭代事件(或令牌)流。 类似于: SAX和Stax

  2. 树模型:它提供了JSON文档的可变内存树表示。 树模型类似于XML DOM。 最佳用例:将 Json数据绑定到Java对象中。 类似于: JAXB

  3. 数据绑定:它根据属性访问器约定或注释将JSON转换为POJO和从POJO转换。 有两种变体:简单和完整数据绑定。 最佳用途:构建树结构(来自Json)并使用合适的方法遍历它。 类似于: DOM

    • 简单的数据绑定意味着转换为Java地图,列表,字符串,数字,布尔值和空值
    • 完整数据绑定意味着转换为任何Java bean类型(以及上面提到的“简单”类型)

通常使用“树模型”方法从“性能角度”被认为是最好的,因为它提供了遍历树的优点。

其他选项也有其自身的优势,例如Streaming API具有较少的内存和CPU开销,数据绑定使用起来很方便,因为它提供了JSON数据的ListMap表示。 然而,由于处理能力和内存如此之多,如今真正重要的是性能。

如果您的JSON数据很大,然后在树表示中分析树是否具有更宽的宽度或更长的长度。 如果它具有更宽的宽度,那么明确地使用“树模型”将具有与树处理相关联的性能优势( 确保您在块中映射而不是一次性完整的东西 )。 但是如果树更长,意思是没有好的宽度但是就像一条很长的尾巴,那么考虑使用“Streaming API”,因为在这种情况下,树处理的优点无法得到证实。 如果数据很小,则几乎不重要,您可以使用“树模型”作为默认值。

目前您正在使用“数据绑定”方法,但建议使用“树模型”,因为您只需要遍历和操纵JSON。 查看您提供的信息,看起来您不需要将JSON转换为Java对象,因此“数据绑定”方法看起来不错。

jackson树模型

jackson的com.fasterxml.jackson.databind.JsonNode构成了jackson树模型的基础。 将Jackson的Tree模型视为HTML文档的DOM, DOM表示树结构中的完整HTML文档的方式,Jackson的Tree模型表示树形结构中的完整JSON字符串。

下面的代码将帮助您使用jackson树模型并实现您的目标:

 import java.io.IOException; import java.util.Iterator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; public class Test { public static void main(String[] args) throws JsonProcessingException, IOException { String jsonString = "{\"test1\": {\"get\": {\"tags\": [\"restcalls1\"]}}, \"test2\": {\"put\": {\"tags\": [\"restcalls2\"] }}}"; ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(jsonString); Iterator iterator2 = rootNode.iterator(); while (iterator2.hasNext()) { JsonNode node2 = iterator2.next().findParent("tags"); ObjectNode objectNode = (ObjectNode) node2; objectNode.putArray("tags").add("my rest calls"); } Iterator iterator = rootNode.iterator(); while (iterator.hasNext()) { JsonNode node2 = iterator.next(); System.out.println(node2); } } } 

树模型优势:

请阅读此处了解更多详情

  • 如果Json内容的结构非常不规则,则可能很难(或不可能)找到或创建等效的Java对象结构。 树模型可能是唯一实用的选择。
  • 用于显示任何JSON内容。 树模型是内部访问和操作的自然选择。
  • 由于我们不需要绑定特定的Java对象,因此可能需要编写的代码较少。

进一步阅读:

  • 有三种 – 也就是三种 – 处理Json的方法
  • 与Jackson一起遍历JSON树
  • Json与Jackson合作

基于OP的评论:

下面的代码显示了如何遍历和打印整个JSON。 通过这种方式,您可以遍历整个JSON,然后访问您要查找的元素。 要注意的是,您需要知道元素名称,即使您使用Stream API方法,您也应该知道要查找的元素名称,请参阅此处的 Stream API示例

在任何情况下,您始终可以选择遍历整个JSON(如下面的示例所示)或进行特定和直接操作(如上例所示)

 package com.him.services; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public class Test { public static void main(String[] args) throws JsonProcessingException, IOException { jacksonTest(); } private static void jacksonTest() throws JsonProcessingException, IOException { String jsonString = "{\"test1\": {\"get\": {\"tags\": [\"restcalls1\"]}}, \"test2\": {\"put\": {\"tags\": [\"restcalls2\"] }}}"; ObjectMapper objectMapper = new ObjectMapper(); JsonNode rootNode = objectMapper.readTree(jsonString); ArrayList nodeList = new ArrayList(); nodeList.add(rootNode); printCompleteJson(nodeList); } private static void printCompleteJson(ArrayList rootNode) throws IOException { for (int i = 0; i < rootNode.size(); i++) { Iterator iterator = rootNode.get(i).iterator(); JsonNode node = null; ArrayList nodeList = new ArrayList(); boolean isEmpty = true; while (iterator.hasNext()) { isEmpty = false; node = iterator.next(); nodeList.add(node); System.out.println(node); } if(isEmpty){ return; } printCompleteJson(nodeList); } } } 

您可以使用Jackson的JsonNode类遍历整个JSON并更改标记的节点值。 请参阅以下代码:

 public class Tags { public static void main(String[] args) throws Exception { InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("tags.json"); ObjectMapper om = new ObjectMapper(); JsonNode node = om.readTree(in); recursiveFind(node); System.out.println(node); //Prints {"test1":{"get":{"tags":["my rest calls"]}},"test2":{"put":{"tags":["my rest calls"]}}} } private static void recursiveFind(JsonNode node) { if (!node.isObject()) { return; } JsonNode tags = node.get("tags"); if (tags != null) { ArrayNode arry = (ArrayNode) tags; arry.removeAll(); arry.add("my rest calls"); } Iterator it = node.elements(); while (it.hasNext()) { JsonNode jsonNode = it.next(); recursiveFind(jsonNode); } } }