How to use Java 8 stream iteration nested for loops to reference parent elements?
•
Java
I want to use the Java 8 stream to iterate over the nested list and extract some results of the list at the first match
How can I do that?
// 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
Solution
When you need two values and want to use flatmap (when performing short circuiting operations like findfirst as needed), you must map to an object containing two 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()); });
To use only standard classes, I use map Entry is the pair type, and the real pair type may look more concise
In this particular use case, you can move a filter action to an internal flow
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()); });
It has a neat effect, with only one matching item, a map The entry instance will be created (well, it should be the current implementation is not as lazy as it should, but even so, it will still create fewer objects than the first variant)
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码