How to iterate nested for loops referring to parent elements using Java 8 streams?

前端 未结 2 566
青春惊慌失措
青春惊慌失措 2021-02-06 04:25

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

相关标签:
2条回答
  • 2021-02-06 04:26

    It should be like this:

    Edit: Thanks Holger for pointing out that the code won't stop at the first valid 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());
      }));
    

    A test can be found here

    0 讨论(0)
  • 2021-02-06 04:35

    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());
      });
    

    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());
      });
    

    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).

    0 讨论(0)
提交回复
热议问题