How to get the next element from a List
using Java 8 Streams?
If I am iterating over a List
, I want to compare current with next element of the list.
Is it doable using Java 8 Stream?
To understand this material, you need to have a basic, working knowledge of Java 8 (lambda expressions, Optional, method references). First of all, Java 8 Streams should not be confused with Java I/O streams (ex: FileInputStream etc); these have very little to do with each other.
It uses the equals () method of the elements to decide whether two elements are equal or not: These operations all take a predicate and return a boolean. Short-circuiting is applied and processing is stopped as soon as the answer is determined: allMatch () checks if the predicate is true for all the elements in the stream.
We can also obtain a stream from an existing list: Note that Java 8 added a new stream () method to the Collection interface. And we can create a stream from individual objects using Stream.of (): Or simply using Stream.builder (): There are also other ways to obtain a stream, some of which we will see in sections below.
It internally uses a java.util.StringJoiner to perform the joining operation. We can also use toSet () to get a set out of stream elements: We can use Collectors.toCollection () to extract the elements into any other collection by passing in a Supplier<Collection>.
My free StreamEx library allows you to process the pairs of the stream elements using additional pairMap
intermediate operation. Like this:
StreamEx.of(input).pairMap((current, next) -> doSomethingWith(current, next));
Where input
is a Collection
, array or Stream
. For example, this way you can easily check whether input is sorted:
boolean isSorted = StreamEx.of(input) .pairMap((current, next) -> next.compareTo(current)) .allMatch(cmp -> cmp >= 0);
There's also forPairs
terminal operation which is a forEach
analog to all pairs of input elements:
StreamEx.of(input).forPairs((current, next) -> doSomethingWith(current, next));
These features work nicely with any stream source (either random access or not) and fully support the parallel streams.
One way is to generate an IntStream
of the indices, and fetch the List
elements by their index. This is only efficient if the List
supports random access (i.e. if your List
is a LinkedList
, it would be a bad idea, since list.get(i)
doesn't take constant time).
For example :
IntStream.range(0,list.size()-1).forEach(i -> { doSomething(list.get(i),list.get(i+1)); });
Another way is to store the last element in an array :
List<Element> list = ... Element[] arr = new Element[1]; list.stream().forEach(e -> { if (arr[0] != null) doSomething(arr[0],e); arr[0]=e; });
This will only work for sequential streams.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With