Java 8 nested streams : return a value in last stream
baskets.stream()
.flatMap(basket -> basket.getItems().stream())
.filter(item -> item.equals("someValue"))
.findAny()
.orElseThrow(NoSuchElementException::new);
The advantage of using findAny
instead of findFirst
is that findFirst
doesn't work with parallel streams. Therefore, if you want to parallelize the above operation all you'll need to do is replace the stream()
method with parallel()
- Use
flatMap
to get ride of nested lists, extract eachList<Item>
and merge them into aStream<Item>
, it acts like all substream were merged together. - Use
filter
to ignore the non matching elements. - Use
findFirst
to get the first occurence only and stop processing - Use
orElseThrow
to throw an exception if no occurence of someValue were found.
Here you go
public class SomeService {
public int findValueInBatch(Batch batch) {
return batch.getBaskets().stream()
.flatMap(basket -> basket.getItems().stream())
.filter(item -> item.getProperty.equals("someValue"))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("value not found"));
}
}
To eliminate both loops you can use flatMap
to produce a Stream<Item>
of all the Item
s of all the Basket
s :
return batch.getBaskets()
.stream()
.flatMap(b -> b.getItems().stream())
.filter(item -> item.getProperty.equals("someValue"))
.findFirst()
.orElse(some default value); // using .get() would throw an exception
// if no match is found