Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate nested for loops referring to parent elements using Java 8 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.

How could I do this?

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
like image 896
membersound Avatar asked Mar 24 '15 14:03

membersound


People also ask

What is a nested for loop in Java?

Nested loop means a loop statement inside another loop statement. That is why nested loops are also called as “ loop inside loop “. Syntax for Nested For loop: Note: There is no rule that a loop must be nested inside its own type. In fact, there can be any type of loop nested inside any type and to any level.

How many times does a for loop iterate in Java?

For example, you can put a while loop inside the body of a for loop. Example 1: Java Nested for Loop. When you run the program, the output will be: Here, the outer loop iterates 5 times. In each iteration of outer loop, the inner loop iterates 2 times.

How to iterate from start to end of an array?

For example, when you are working with single-dimensional Array, you can use Java For Loop to iterate from starting to array end. However, to work with Two Dimensional array or Multi Dimensional Array, you have to use this Nested For Loop in Java.

What are streams in Java 8?

Streams are one of the most significant features to come out of Java 8. To find out why they are useful, you will need to understand what a stream is in Java. A stream is a sequence of data that allows for a special type of processing on all or just some of the data. We can create streams or transform existing structures into streams.


Video Answer


1 Answers

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

like image 167
Holger Avatar answered Oct 22 '22 10:10

Holger