代码之家  ›  专栏  ›  技术社区  ›  James-Jesse Drinkard

如何使用Java8通过匹配映射中的键从JSON对象中提取a值?

  •  2
  • James-Jesse Drinkard  · 技术社区  · 6 年前

    我正在使用java8和jackson尝试从json对象获取int值。下面是一些我用来验证结构的类似代码。

    HashMap<String, Object> myMap = new HashMap<String, Object>();  
    myMap
            .entrySet()
            .stream()
            .forEach(x -> System.out.println(x.getKey() + " => " + x.getValue()));
    

    结果是:

    myKey2=>{“数字“:1}

    myKey3=>{“数字“:2}

    我要做的是使用这个键,比如myKey1来找到json值,即{“number”:1},然后取出实际的数字,这个键的数字是1。

    我想因为我不知道键和它们的顺序,再加上我使用entrySet,这就迫使我使用Optional,这使得这变得更加困难。

    Optional<Object> object = myMap.entrySet().stream()
            .filter(e -> e.getKey().equals(myKey))
            .map(Map.Entry::getValue)
            .findFirst();
    

    然而,这条溪流退了回来

    可选[{“数字”:1}]

    有一个对象的Java类,所以我假设这就是为什么它返回Optional,因为我得到了一个编译错误,没有它,但我不确定。

    关于正确的方法有什么想法吗?

    3 回复  |  直到 6 年前
        1
  •  3
  •   fps    6 年前

    为什么要迭代映射的所有条目并按键进行线性搜索,以获得条目的值?

    直接获取值:

    Object value = myMap.get(myKey);
    

    现在,关于里面的数字 value Map 地图 :

    Integer = null;
    
    if (value != null) {
        // What's the type of the value? Maybe a Map?
        if (value instanceof Map) {
            Map<String, Object> valueAsMap = (Map<String, Object>) value;
            number = (Integer) valueAsMap.get("number");
        }
    }
    

    我假设数字是 Integer s、 但他们完全可以 Long 实例,甚至 Double BigDecimal


    编辑: 为完整起见,以下是值不是映射,而是表示json节点的某个类的值时的代码。这里我使用的是来自Jackson库的JsonNode,但是对于其他lib,方法非常相似:

    Integer = null;
    
    if (value != null) {
        if (value instanceof JsonNode) {
            JsonNode valueAsNode = (JsonNode) value;
            number = (Integer) valueAsNode.get("number").numberValue();
        }
    }
    
        2
  •  1
  •   Kartik    6 年前

    findFirst() 返回一个 Optional .get() .orElse() .orElseThrow() 你打电话之后 findFirst() .

    然后你可以投下 Object JsonNode 并检索值。这是完整的code:-

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        HashMap<String, Object> myMap = new HashMap<String, Object>();
        myMap.put("myKey1", mapper.readTree("{\"number\":1}"));
        myMap.put("myKey2", mapper.readTree("{\"number\":1}"));
        myMap.put("myKey3", mapper.readTree("{\"number\":2}"));
    
        System.out.println(getNumberUsingMapKey(myMap, "myKey3"));
    }
    
    private static int getNumberUsingMapKey(Map<String, Object> map, String key) throws Exception {
        return Optional.of(map.get(key))
                .map(o -> ((JsonNode) o).get("number").asInt())
                .get(); //or use one of the following depending on your needs
    //                .orElse(-1);
    //                .orElseThrow(Exception::new);
    }
    
    //or use this method
    private static int getNumberUsingMapKeyWithoutOptional(Map<String, Object> map, String key) throws Exception {
        Object o = map.get(key);
        return ((JsonNode) o).get("number").asInt();
    }
    

    输出

    2

        3
  •  0
  •   James-Jesse Drinkard    6 年前

    不幸的是,我没有从一开始就很好地描述我的问题陈述,但这是我能够从其他答案中拼凑出的最终工作代码。

    这就是数据结构的样子。一个键,它的值是一个JSON对象,它有一个键和一个int,换句话说就是一个嵌套的JSON对象。

    Key:myKey2值:{“number”:1}

    Key:myKey3值:{“number”:2}

          Object value = myMap.get(keyName);
          ObjectMapper mapper = new ObjectMapper();
          String jsonString = (String) value;
          JsonNode rootNode = mapper.readTree(jsonString);    
          JsonNode numberNode = rootNode.path("number");
          System.out.println("number: " + numberNode.intValue());
    

    数量:1