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

如何使用Java8通过匹配映射中的键从JSON对象中提取a值?,json,java-8,jackson,Json,Java 8,Jackson,我正在使用Java8和jackson尝试从json对象获取int值。下面是一些我用来验证结构的类似代码 HashMap<String, Object> myMap = new HashMap<String, Object>(); myMap .entrySet() .stream() .forEach(x -> System.out.println(x.getKey() + " => " + x.getVal

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

HashMap<String, Object> myMap = new HashMap<String, Object>();  
myMap
        .entrySet()
        .stream()
        .forEach(x -> System.out.println(x.getKey() + " => " + x.getValue()));
HashMap myMap=newhashmap();
我的地图
.entrySet()
.stream()
.forEach(x->System.out.println(x.getKey()+“=>”+x.getValue());
结果是:

myKey1=>{“数字”:1}

myKey2=>{“数字”:1}

myKey3=>{“数字”:2}

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

但是,我不知道所有键的值,只知道我要匹配的键。所以我必须动态地这样做。我知道这些值的结构,它们总是一样的,只是数字可能不同

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

下面是我的代码,我实际上是在使用键提取json值:

Optional<Object> object = myMap.entrySet().stream()
        .filter(e -> e.getKey().equals(myKey))
        .map(Map.Entry::getValue)
        .findFirst();
Optional object=myMap.entrySet().stream()
.filter(e->e.getKey().equals(myKey))
.map(map.Entry::getValue)
.findFirst();
然而,这条溪流退了回来

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

我似乎无法得到数字,所以我可以从一个方法返回它。其实我不知道 有一个Java类用于对象,所以我假设这就是为什么它返回可选的原因,因为我得到了一个没有它的编译错误,但我不确定

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

findFirst()
返回一个
可选的
。在调用
findFirst()
之后,需要调用
.get()
.orElse()
.orelsetrow()

然后可以将
对象
强制转换为
JsonNode
并检索值。以下是完整的代码:-

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();
}
publicstaticvoidmain(字符串[]args)引发异常{
ObjectMapper mapper=新的ObjectMapper();
HashMap myMap=新HashMap();
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”);
}
私有静态int GetNumberSingMapKey(映射映射,字符串键)引发异常{
返回可选的.of(map.get(key))
.map(o->((JsonNode)o).get(“number”).asInt()
.get();//或根据需要使用以下选项之一
//.orElse(-1);
//.orelsetrow(异常::新建);
}
//或者用这个方法
私有静态int GetNumberSingMapKeyWithOutOptional(映射映射,字符串键)引发异常{
对象o=map.get(键);
return((JsonNode)o.get(“number”).asInt();
}
输出


2

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

直接获取值即可:

Object value = myMap.get(myKey);
现在,关于
value
中的数字,正如您所说,您没有一个表示映射值的类,最有可能的是您使用的JSON库正在为每个值创建一个
map
。从现在开始,我们假设这些值实际上是
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");
    }
}

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

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

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

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


地图上的值是什么类型的?是内部地图吗?可能是一个
JSONObject
或某个JSON库中的其他对象?一些自定义类?只是一个字符串键,它的值是一个json对象,它有另一个键和和int,是的,我检查了它是有效的json。很抱歉没有说得更清楚。我想通过传入的键名循环映射到方法中的键以匹配该键,然后从匹配键的json值中提取int值,如果这有意义的话。是的,这部分工作正常,但值是json,不是映射,但多亏了您的帮助和Kartik,我才能够找到它。Te damos gracias para tu ayuda!杰克逊2.8x。以下是导入:import com.fasterxml.jackson.core.JsonFactory;导入com.fasterxml.jackson.core.JsonProcessingException;导入com.fasterxml.jackson.databind.JsonNode;导入com.fasterxml.jackson.databind.ObjectMapper;我尝试了一些其他的LIB,但这已经在代码中,并且处理了我需要的一切。@James谢谢!我也使用Jackson;)它非常完整。我一直在让InvocationTargetException运行此代码,并且java.lang.ClassCastException:java.lang.String无法转换为com.fasterxml.jackson.databind.JsonNode。
      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());