How to Get the Last Element of a Stream in Java?

1. Overview

The Java Stream API was the major feature of the Java 8 release. Streams represent lazily-evaluated sequences of objects and provide a rich, fluent, and monadic-like API.

In this article, we will have a quick look into ways of getting the last element of a Stream. Keep in mind that due to the nature of streams, it’s not a natural operation. Always make sure that you’re not working with infinite Streams.

2. Using the Reduce API

Reduce, simply put, reduces the set of elements in a Stream to a single element.

In this case, we’ll reduce the set of elements to get the last element fn the Stream. Keep in mind that this method will only return deterministic results for sequential Streams.

Let’s use a List of String values, get the Stream from the List and then reduce:

List<String> valueList = new ArrayList<>();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");

Stream<String> stream = valueList.stream();
stream.reduce((first, second) -> second)
  .orElse(null);

Here, the stream is reduced to a level where it is left with only the last element. If the stream is empty it will return a null value.

2. Using the Skip Function

The other way to get the last element of the stream is by skipping all the elements before it. This can be achieved using Skip function of Stream class. Keep in mind that in this case, we are consuming the Stream twice so there is some clear performance impact.

Let’s create a List of string values and use its size function to determine how many elements to skip to reach the last element.

Here is the example code getting the last element using skip:

List<String> valueList = new ArrayList<String>();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");

long count = valueList.stream().count();
Stream<String> stream = valueList.stream();
   
stream.skip(count - 1).findFirst().get();

Sean” ends up being the last element.

4. Getting the Last Element of an Infinite Stream

Trying to get the last element of the infinite stream would lead to an infinite sequence of evaluation performed on infinite elements. Both skip and reduce will not come back from the execution of evaluation unless we limit the infinite stream to a specific number of elements using limit operation.

Here is the example code where we took an infinite stream and tried to get the last element:

Stream<Integer> stream = Stream.iterate(0, i -> i + 1);
stream.reduce((first, second) -> second).orElse(null);

Consequently, the stream will not come back from the evaluation and it will end up halting the execution of the program.

5. Conclusion

We saw different ways of getting the last element of a Stream both using reduce and Skip APIs. We also looked into why this is not possible with infinite streams.

We saw that getting the last element from a Stream is not easy in comparison to fetching it from other data structures. This is because of the lazy nature of Streams which are not evaluated unless the terminal function is invoked and we never know if the currently evaluated element is the last one.

Code snippets can be found over on GitHub.

Related posts:

Quick Guide to @RestClientTest in Spring Boot
Iterating over Enum Values in Java
Converting Between a List and a Set in Java
Java Program to Check if an UnDirected Graph is a Tree or Not Using DFS
Java Program to Perform Naive String Matching
Tránh lỗi ConcurrentModificationException trong Java như thế nào?
Java Program to Implement TreeSet API
RegEx for matching Date Pattern in Java
Show Hibernate/JPA SQL Statements from Spring Boot
Assert an Exception is Thrown in JUnit 4 and 5
Java Program to Implement Solovay Strassen Primality Test Algorithm
Spring Security OAuth2 – Simple Token Revocation
Java Program to Implement Sorting of Less than 100 Numbers in O(n) Complexity
Registration – Password Strength and Rules
Java Program to Implement the Schonhage-Strassen Algorithm for Multiplication of Two Numbers
Spring Boot Gradle Plugin
Pagination and Sorting using Spring Data JPA
Format ZonedDateTime to String
Java Program to Implement Bloom Filter
The Registration API becomes RESTful
Using Spring @ResponseStatus to Set HTTP Status Code
Java Program to Use rand and srand Functions
Converting Between an Array and a Set in Java
Guide to ThreadLocalRandom in Java
Guide to the Java Clock Class
Java Program to Implement Stack
Tạo ứng dụng Java RESTful Client với thư viện Retrofit
Java Program to Find Transitive Closure of a Graph
Collection trong java
Java Program to Check whether Graph is a Bipartite using BFS
Java Program to Solve Travelling Salesman Problem for Unweighted Graph
Java Program to Find the Nearest Neighbor Using K-D Tree Search