【问题标题】:Optimize Stream Support operations Java优化流支持操作 Java
【发布时间】:2019-04-17 04:21:56
【问题描述】:

我有一个像这样的 ArrayNode 名称 "results":

[{
"subjectName": "Eclipse",
"code": "EC1",
"states": [
    {
        "subjectName": "LunorEx1",
        "code":"E1"
    },
    {
        "subjectName": "LunorEx2",
        "code":"E2"
    },
    {
        "subjectName": "Expus LunorEx3 ", 
        "code":"E6"
    }]
},
{
"subjectName": "Lasena",
"code": "LS1",
"states": [
    {
        "subjectName": "SunorEx1",
        "code":"S1"
    },
    {
        "subjectName": "SunorEx2",
        "code":"S2"
    }]
}, {
"subjectName": "Gilesh",
"code": "GL2",
"states": [ ]
}]

这个变量是公开的。

使用 Java 8,我希望能够检查是否存在,例如,subjectName 等于“Eclipse”并且代码等于“EC1”,如果存在,那么我想在它的 json 状态中搜索并找到一个状态例如,subjectName 等于“LunorEx1”和代码“E1”,如果找到所有这些我想返回 true

private static boolean subjectValidation( String parentSubjectName, String parentCode, String childSubjectName, String childCode){

    boolean valid = false;
    try {
            JsonNode subjectData = StreamSupport.stream(results.spliterator(), true)
                    .filter(c -> c.get("subjectName").asText().equals(parentSubjectName) &&
                            c.get("code").asText().equals(parentCode) )
                    .collect(Collectors.toList()).get(0);

            valid = StreamSupport.stream(subjectData.get("states").spliterator(), true)
                    .anyMatch(k ->  k.get("states").get("subjectName").asText().equals(childSubjectName) &&
                            k.get("states").get("code").asText().equals(childCode));



    } catch (Exception e) {
    }
    return valid;
}

我想优化这个,因为我有几个具有相同结构的 JSON 数组,并且我做了几个类似的检查......。并在第一流返回时处理。 有人可以帮助我,就如何更好地做到这一点提供一些建议吗?

【问题讨论】:

  • 不要使用collect(toList()).get(0):使用findFirst().get()(跳过get来处理“未找到”的情况:它会给你一个Optional<JsonNode>)。
  • 请添加一个“json”标签。我认为您自己提供答案。为您描述的所有功能制作单独的功能:检查 subjectName "Eclipse" 是一个功能,也是一个功能。如果您有很多小功能,则将它们组合起来会更容易。
  • @RalfRenz 你能帮我更多地理解你的建议吗?所以基本上你,因为我在这里检查 4 个值,我应该做 4 个函数来做检查,这是你的建议吗?
  • @RalfRenz 这是有道理的,因为我还必须返回一条消息,它在父主题代码或名称或子主题名称和代码中失败。但我不知道该怎么做,我想检查主题数据是否不为空,这意味着父主题是有效的..:/
  • 不一定。您应该尽可能地进行参数化。 c.get("subjectName").asText().equals(parentSubjectName)的结构是:var1.get(var2).asText().equals(var3)。您可以使用三个参数 var1、var2、var3 对其进行函数化并重复使用。

标签: java java-8 java-stream filtering


【解决方案1】:

我认为它可能看起来像这样:

private static boolean subjectValidation(String parentSubjectName, String parentCode, String childSubjectName,
        String childCode) {

    boolean valid = false;
    try {
        Optional<JsonNode> subjectData = StreamSupport.stream(results.spliterator(), true)
                .filter(c -> exists(c, "subjectName", parentSubjectName) && exists(c, "code", parentCode))
                .findFirst();

        if (subjectData.isPresent()) {
            valid = StreamSupport.stream(subjectData.get().get("states").spliterator(), true)
                    .anyMatch(k -> exists(k.get("states"), "subjectName", childSubjectName)
                            && exists(k.get("states"), "code", childCode));
        }

    } catch (Exception e) {
    }
    return valid;
}

private static boolean exists(JsonNode node, String nodeName, String value) {
    return node.get(nodeName).asText().equals(value);
}

【讨论】:

  • 我会在任意匹配之前的第二个流中添加一个 map(k -> k.get("states")) 以防止该操作必须发生两次
  • @RalfRenz 这很有帮助
【解决方案2】:

我想考虑到 subjectName 和 code 不是唯一的。

private static boolean subjectValidation(String parentSubjectName, String parentCode, String childSubjectName, String childCode) {

    try {
        return StreamSupport.stream(results.spliterator(), true)
            .filter(c -> hasSubject(c, parentSubjectName) && hasCode(c, parentCode))
            .flatmap(s -> StreamSupport.stream(s.get("states").spliterator(), true)
            .map(k -> k.get("states"))
            .anyMatch(k -> hasSubject(k, childSubjectName) && hasCode(k, childCode));
    } catch (Exception e) {
        return false;
    }
}

private static boolean hasSubject(JsonNode node, String value) {
    return fieldHasValue(node, "subjectName", value);
}

private static boolean hasCode(JsonNode node, String value) {
    return fieldHasValue(node, "code", value);
}

private static boolean fieldHasValue(JsonNode node, String field, String value) {
    return node.get(field).asText().equals(value);
}

应该有更好的异常处理,但它应该可以工作。

如果您想进一步概括这一点,我会创建一个函数,让您可以根据“代码”、“主题名”和“状态”的设置变量即时进行这些检查

【讨论】:

    猜你喜欢
    • 2016-10-09
    • 1970-01-01
    • 2023-02-13
    • 2011-09-11
    • 2014-06-30
    • 1970-01-01
    • 2011-02-28
    • 2014-03-31
    • 2022-11-24
    相关资源
    最近更新 更多