使用Java8Lambas按键或值在JsonArray(javax.json.JsonArray)中查找JsonObject

使用Java8Lambas按键或值在JsonArray(javax.json.JsonArray)中查找JsonObject,java,java-8,java-stream,Java,Java 8,Java Stream,关于如何使用Java8Lambdas在JsonArray(javax.json.JsonArray)中快速定位JsonObject,我还没有找到一个简洁/最新的答案。所有关于循环的答案都太冗长了 如果我有 JsonArray answersArray = ... 数组是 [ { "activityQuestionId": "875", "questionType": "STARTTIME", "answer": "12:45am"

关于如何使用Java8Lambdas在
JsonArray
javax.json.JsonArray
)中快速定位
JsonObject
,我还没有找到一个简洁/最新的答案。所有关于循环的答案都太冗长了

如果我有

JsonArray answersArray  = ...
数组是

[   {
        "activityQuestionId": "875",
        "questionType": "STARTTIME",
        "answer": "12:45am"
    }, {
        "activityQuestionId": "876",
        "questionType": "ENDTIME",
        "answer": "1:00am"
    }, 
    ...
    {
        "activityQuestionId": "SPECIAL",
        "questionType": "DROPDOWN",
        "answer": "756", 
        "extra": "SPECIAL/EXTRA"
    }
]
通常情况下,我能做到

JsonArray answersArray  = ...
JsonObject obj1 = answersArray.getJsonObject(1); // This brings back 2nd object 
String str = obj1.getString("answer"); // This brings back 1:00am answer in 2nd object
我需要做以下工作:

  • 按键查找:找到具有键的
    JsonObject
    “extra”。只有一个对象有它(最后一个),所以这就是我应该得到的对象
  • 按某个键的值查找:查找
    JsonObject
    具有
    “activityQuestionId”:“SPECIAL”
    。应返回相同的最后一个对象
JsonArray

试试这个

JsonObject jsonObject= answersArray.getJsonObject(1) // 1 is the second index in the json array
String activityQuestionId= jsonObject.getString("activityQuestionId");
String questionType= jsonObject.getString("questionType");

试试这个。这应该行得通

 final Optional<Object> extra = IntStream.range(0, jsonArray.length())
                .mapToObj(i -> getJsonObject(jsonArray, i))
                .filter(Objects::nonNull)
                .map(this::getObject)
                .filter(Objects::nonNull)
                .findFirst();
     //if extra.isPresent() then do extra.get() to get the value
    }

   //Instead of returning a generic type try to return specific type
   //Better Exception handling
    private Object getObject(JSONObject entry) {
        try {
            return entry.get("extra");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    private JSONObject getJsonObject(JSONArray jsonArray, int i) {
        try {
            return jsonArray.getJSONObject(i);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
final Optional extra=IntStream.range(0,jsonArray.length())
.mapToObj(i->getJsonObject(jsonArray,i))
.filter(对象::非空)
.map(this::getObject)
.filter(对象::非空)
.findFirst();
//如果是extra.isPresent(),则执行extra.get()以获取值
}
//尝试返回特定类型,而不是返回泛型类型
//更好的异常处理
私有对象getObject(JSONObject条目){
试一试{
返回条目。获取(“额外”);
}捕获(JSONException e){
e、 printStackTrace();
}
返回null;
}
私有JSONObject getJsonObject(JSONArray JSONArray,inti){
试一试{
返回jsonArray.getJSONObject(i);
}捕获(JSONException e){
e、 printStackTrace();
}
返回null;
}
这不是一个完整的解决方案。这应该会让你知道如何接近。如果您想将lamdas用于此类代码,您应该检查如何在lambdas中处理异常,因为json处理会抛出大量已检查的异常。你不能只是从兰博达斯里面扔,你需要处理它


您需要考虑使用Streams是否是此场景的一种好方法,或者它是否是一种过度杀伤力。

找到具有键“extra”的JsonObject

找到具有“activityQuestionId”的JsonObject:“特殊”

解决方案

List<JsonValue> objects1 = answersArray.stream().filter(obj -> 
            ((JsonObject)obj).getString("extra") != null).collect(Collectors.toList());

List<JsonValue> objects2 = answersArray.stream().filter(obj ->      
            "SPECIAL".equals(((JsonObject)obj).getString("activityQuestionId")).collect(Collectors.toList());
List objects1=answersArray.stream().filter(obj->
((JsonObject)obj.getString(“额外”)!=null.collect(Collectors.toList());
List objects2=answersArray.stream().filter(obj->
“SPECIAL”.equals((JsonObject)obj).getString(“activityQuestionId”).collect(Collectors.toList());

编写流代码的哪一部分让您感到不安?因为
JsonArray
是一个
列表
,您可以在其上调用
stream()
。要查找某个内容,您可以使用
过滤器(…)
findFirst()
。这些都相当简单,而且在web上有许多使用它们的示例,所以您尝试了什么,这对您不起作用吗?“无法找到[…]如何使用Java 8 Lambdas快速定位[…]”真的吗?网络搜索:困难在于
过滤器
这里没有你可以测试的密钥。你可以获取(“stringConstant”),但你不能轻易地获取密钥集并对其进行迭代。“你没有在这里获取你可以测试的密钥”获取密钥是你的工作:
.filter(obj->“bar.”equals(obj.get(“foo”))
将过滤掉所有没有
foo
的对象和
foo
不是
的对象“bar”
不,您不能在
JsonValue
上执行
get(“foo”)
。这是不受支持的操作。这是如何回答“按键查找”和“按值查找”的问题的?在按键查找中,如果(jsonObject.containsKey(“extra”)在按值查找中,循环到每个jsonObject中,检查是否有值
特殊
,这如何适用于您的答案中的任何内容?
JsonObject activityIdSpecialJsonObject = value.stream()
        .map(JsonValue::asJsonObject)
        .filter(jo -> "SPECIAL".equals(jo.getString("activityQuestionId", null)))
        .findFirst()
        .orElse(null);// or something else
List<JsonValue> objects1 = answersArray.stream().filter(obj -> 
            ((JsonObject)obj).getString("extra") != null).collect(Collectors.toList());

List<JsonValue> objects2 = answersArray.stream().filter(obj ->      
            "SPECIAL".equals(((JsonObject)obj).getString("activityQuestionId")).collect(Collectors.toList());