Learn to find the last element of a stream in Java. We will learn to use finite as well as infinite streams as well.
1. Getting Last Item with Stream Reduction
The reduce()
method uses the reduction technique on the elements of the Stream. To get the last element, it continues picking up the two elements of the stream and choosing the latter. This will go on until all elements are exhausted.
At the end of the reduction process, we will have the last element of the stream.
Stream<Integer> stream = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)
.stream();
Integer lastElement = stream.reduce((first, second) -> second)
.orElse(-1);
System.out.println(lastElement); // Prints 9
The reduce()
method returns an Optional
which gives us the choice of what to do when an empty element is returned. For example, the stream itself might be empty.
Stream<Integer> emptyStream = Stream.empty();
//Return -1 if stream is empty
Integer lastElement = emptyStream.reduce((first, second) -> second)
.orElse(-1);
System.out.println(lastElement); //-1
//Throw IllegalStateException if stream is empty
Integer lastElement = emptyStream.reduce((first, second) -> second)
.orElseThrow(() -> new IllegalStateException("no last element"));
Program output:
-1
Exception in thread "main" java.lang.IllegalStateException: no last element
at com.howtodoinjava.core.streams.misc.GetLastElement.lambda$1(GetLastElement.java:19)
at java.util.Optional.orElseThrow(Unknown Source)
at com.howtodoinjava.core.streams.misc.GetLastElement.main(GetLastElement.java:19)
2. Using Streams.findLast() from Guava
Streams.findLast() is really neat, readable, and provides good performance. It returns the last element of the specified stream, or Optional.empty()
if the stream is empty.
Stream<Integer> stream = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)
.stream();
Integer lastElement = Streams.findLast(stream2).orElse(-1);
System.out.println(lastElement); // Prints 9
3. Last Item from an Infinite streams
Can there be any last element in an infinite stream? No, there cannot be. So make sure that the stream is not infinite when we are trying to find the last element of the stream. None of the above-listed APIs will return any value or throw an exception.
In fact, the above solutions will not even return and halt the program execution completely.
Stream<Integer> stream = Stream.iterate(0, i -> i + 1);
Integer lastElement = Streams.findLast(stream).orElse(-1); // Halts the program
System.out.println(lastElement);
Use limit()
to get a finite stream out of a given infinite stream.
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
lastElement = infiniteStream.limit(100)
.reduce((first, second) -> second)
.orElse(-1);
System.out.println(lastElement); //198
Drop me your questions in the comments related to how to find the last element of a stream.
Happy Learning !!