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

查看:242
本文介绍了如何使用Java 8流迭代嵌套for循环引用父元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用java8 streams 迭代嵌套列表,并在第一次匹配时提取列表的一些结果。
不幸的是,如果子元素与过滤器匹配,我还必须从父内容中获取值。

I want to iterate nested lists using java8 streams, and extract some results of the lists on first match. Unfortunately I have to also get a values from the parent content if a child element matches the filter.

我怎么能这样做?

// java7

Result result = new Result();

//find first match and pupulate the result object.
for (FirstNode first : response.getFirstNodes()) {
    for (SndNode snd : first.getSndNodes()) {
        if (snd.isValid()) {
            result.setKey(first.getKey());
            result.setContent(snd.getContent());
            return;
        }
    }
}

// java8

 response.getFirstNodes().stream()
        .flatMap(first -> first.getSndNodes())
        .filter(snd -> snd.isValid())
        .findFirst()
        .ifPresent(???); //cannot access snd.getContent() here


推荐答案

你需要两个值并且想要使用 flatMap (当你想要执行像 findFirst 这样的短路操作时需要),你必须映射到一个包含两个值的对象

When you need both values and want to use flatMap (as required when you want to perform a short-circuit operation like findFirst), you have to map to an object holding both values

response.getFirstNodes().stream()
  .flatMap(first->first.getSndNodes().stream()
    .map(snd->new AbstractMap.SimpleImmutableEntry<>(first, snd)))
  .filter(e->e.getValue().isValid())
  .findFirst().ifPresent(e-> {
    result.setKey(e.getKey().getKey());
    result.setContent(e.getValue().getContent());
  });

为了仅使用标准类,我使用 Map.Entry 作为Pair类型,而真正的Pair类型可能看起来更简洁。

In order to use standard classes only, I use a Map.Entry as Pair type whereas a real Pair type might look more concise.

在这个特定用例中,您可以将过滤操作移动到内部流

In this specific use case, you can move the filter operation to the inner stream

response.getFirstNodes().stream()
  .flatMap(first->first.getSndNodes().stream()
     .filter(snd->snd.isValid())
     .map(snd->new AbstractMap.SimpleImmutableEntry<>(first, snd)))
  .findFirst().ifPresent(e-> {
    result.setKey(e.getKey().getKey());
    result.setContent(e.getValue().getContent());
  });

其效果很好,仅适用于一个匹配的商品,地图将创建.Entry 实例(好吧,应该作为当前的实施不是尽管它应该是懒惰的但是即使这样它仍会产生比第一个变体更小的物体。)

which has the neat effect that only for the one matching item, a Map.Entry instance will be created (well, should as the current implementation is not as lazy as it should but even then it will still create lesser objects than with the first variant).

这篇关于如何使用Java 8流迭代嵌套for循环引用父元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆