简体   繁体   English

您将如何使用 Java Stream API 编写此代码? 与此代码相比,优势是什么?

[英]How would you write this code using the Java Stream API? And what would be the advantage compared to this code?

I tried to write the following code using the stream API, but found that being not able to access the Parent objects in the stream of Grandchild objects, it is way easier to use classic for-loops.我尝试使用 stream API 编写以下代码,但发现无法访问 stream 中的 Parent 对象 Grandchild 对象,使用经典 forloops 更容易。 How could a solution using the stream API look like?使用 stream API 的解决方案如何? And are there any advantages to such a solution?这种解决方案有什么好处吗? The task is to find certain elements in a structure like this: parent -> List -> List and to get for each matching Grandchildren a String of nameOfParent.nameOfGrandchild.任务是在这样的结构中找到某些元素:parent -> List -> List 并为每个匹配的 Grandchildren 获取 nameOfParent.nameOfGrandchild 的 String。 Simple, working code with for-loops:带有 for 循环的简单有效代码:

        List<String> grandchilds = new ArrayList<>();
        for (Parent parent : parents) {
            String parentName = parent.getName() + ".";
            for (Child child : parent.getChilds()) {
                if (null != child.getTags() && child.getTags().size() == 1
                        && SEARCHED_TAG.equals(child.getTags().get(0))) {
                    for (Grandchild gc : child.getGrandchilds()) {
                        grandchilds.add(parentName + gc.getName());
                    }
                }
            }
        }

I was at this point using stream API where i realized that accessing properties of parent is no longer possible when i have the stream of Grandchild.此时我正在使用 stream API ,我意识到当我拥有孙子的 stream 时,不再可能访问父级的属性。

            List<Grandchild> grandchildren = parents.stream()
                .flatMap(parent -> parent.getChilds().stream())
                .filter(child -> null != child.getTags() && child.getTags().size() == 1 && SEARCHED_TAG.equals(child.getTags().get(0)))
                .flatMap(child -> child.getGrandchilds().stream())
                .collect(Collectors.toList());        

I found some hints like in the following questions, but the resulting code seemed unnecessarily complex and there is the occasional recommendation to use for-loops instead.我在以下问题中发现了一些提示,但生成的代码似乎不必要地复杂,并且偶尔建议使用 for 循环。

Access element of previous step in a stream or pass down element as "parameter" to next step? 访问 stream 中上一步的元素还是将元素作为“参数”传递给下一步?

Get parent object from stream 从 stream 获取父 object

How to iterate nested for loops referring to parent elements using Java 8 streams? 如何使用 Java 8 个流迭代引用父元素的嵌套 for 循环?

Rather than chaining flatMap() calls in a single pipeline, nest one inside the other:与其将flatMap()调用链接在单个管道中,不如将一个嵌套在另一个中:

List<String> grandchilds = parents.stream()
  .flatMap(parent -> parent.getChilds().stream()
    .filter(tagMatch(SEARCHED_TAG))
    .flatMap(child -> child.getGrandchilds().stream().map(gc -> parent.getName() + "." + gc.getName())))
  .toList();

private static Predicate<Child> tagMatch(String tag) {
  return child -> {
    List<String> tags = child.getTags();
    return tags != null && tags.size() == 1 && tags.get(0).equals(tag);
  };
}

I didn't test that and may have missed a parens in there, but that's the gist of it.我没有对此进行测试,并且可能在那里错过了一个括号,但这就是它的要点。

As far as advantages go, I don't see any.至于优势 go,我没有看到。 That aspect is opinion-based, but in my opinion, the for-loops are easier to read and verify, even after factoring out the rather complicated filtering predicate.这方面是基于意见的,但在我看来,for 循环更容易阅读和验证,即使在考虑了相当复杂的过滤谓词之后也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM