如何使用Java8流迭代引用父元素的嵌套for循环?

如何使用Java8流迭代引用父元素的嵌套for循环?,java,java-8,java-stream,optional,Java,Java 8,Java Stream,Optional,我想使用java8streams迭代嵌套列表,并在第一次匹配时提取列表的一些结果。 不幸的是,如果子元素与过滤器匹配,我还必须从父内容中获取一个值 我怎么能这样做 java7 Result result = new Result(); //find first match and pupulate the result object. for (FirstNode first : response.getFirstNodes()) { for (SndNode snd : first.

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

我怎么能这样做

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

应该是这样的:

编辑:感谢Holger指出代码不会在第一个有效的FirstNode处停止

response.getFirstNodes().stream()
  .filter(it -> {it.getSndNodes().stream().filter(SndNode::isValid).findFirst(); return true;})
  .findFirst()
  .ifPresent(first -> first.getSndNodes().stream().filter(SndNode::isValid).findFirst().ifPresent(snd -> {
    result.setKey(first.getKey());
    result.setContent(snd.getContent());
  }));

当您需要这两个值并且想要使用
flatMap
时,可以找到测试(当您想要执行类似
findFirst
的短路操作时需要),您必须映射到包含这两个值的对象

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
实例(当然,即使如此,它仍然会创建比第一个变量更少的对象)。

这可能的副本没有任何用处。问题的原始代码名为
result.setKey(first.getKey());result.setContent(snd.getContent())并停止处理后续项目。您的代码没有这样做。我正在演示如何在
ifPresent()
中访问
snd.getContent()
,我已经修改了代码now@Holger我可以取消-1吗?我已经测试过我的代码是否正常工作,是否符合op的意图。我没有否决投票,所以我对此无能为力。此外,使用
forEach
仍然无法解决问题的任务,即在第一次匹配后停止。当然,仅使用一个匹配项进行测试不会表现出这种行为……没有问题,感谢您指出我代码中的错误。我现在已经修改了代码,以执行正确的操作。我将把答案留在那里,因为它是正确的。无论是谁认为这个答案值得否决,如果告诉我原因,都会有所帮助。谢谢你的解释。看看你的代码,我觉得最好还是坚持java7风格的迭代风格,以防需要访问多个/父元素。是的,好的
for
循环并没有过时。也许未来的Java版本支持成对/元组的语言,为更好的流解决方案提供了可能…
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());
  });