Reverse a Sequential Stream in Java
This post will discuss how to reverse a sequential stream in Java. Since streams don’t store any elements, an intermediate collection is used to create a new stream which iterates elements of the specified stream in reverse order.
1. Using LinkedList
The simplest solution is to use the linked list data structure. We know that the LinkedList class in Java is implemented as a stack and supports insertion at the beginning. So the idea is to insert elements of the specified stream into a LinkedList and return the stream to that list.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.LinkedList; import java.util.stream.Stream; // Program to reverse elements of a sequential stream in Java class Main { public static <T> Stream<T> reverse(Stream<T> stream) { LinkedList<T> stack = new LinkedList<>(); stream.forEach(stack::push); return stack.stream(); } public static void main(String[] args) { Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); Stream<Integer> reverse = reverse(stream); reverse.forEach(System.out::println); } } |
2. Using Collectors
Another simple solution involves using Collectors. We can use the collectingAndThen() method to adapt the toList() collector to produce a list in reverse order, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.util.Collections; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; // Program to reverse elements of a stream in Java class Main { public static <T> Collector<T, ?, Stream<T>> reverse() { return Collectors.collectingAndThen(Collectors.toList(), list -> { Collections.reverse(list); return list.stream(); }); } public static void main(String[] args) { Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); Stream<Integer> reverse = stream.collect(reverse()); reverse.forEach(System.out::println); } } |
Since the LinkedList class in Java supports insertion at the front, it provides descending iterators. We can use this to iterate the stream in reverse order, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.Iterator; import java.util.LinkedList; import java.util.stream.Collectors; import java.util.stream.Stream; // Program to reverse elements of a sequential stream in Java class Main { public static <T> Iterator<T> reverse(Stream<T> stream) { return stream.collect(Collectors.toCollection(LinkedList::new)) .descendingIterator(); } public static void main(String[] args) { Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); Iterator<Integer> reverse = reverse(stream); reverse.forEachRemaining(System.out::println); } } |
ArrayDeque can also be used in place of LinkedList:
|
1 2 3 4 |
public static <T> Iterator<T> reverse(Stream<T> stream) { return stream.collect(Collectors.toCollection(ArrayDeque::new)) .descendingIterator(); } |
3. Using Collector.of() method
Collector interface provides static factory methods of(Supplier, BiConsumer, BinaryOperator, Characteristics…) can be used to construct collectors. The idea is to create a collector that accumulates elements of the specified stream into an ArrayList in reverse order.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collector; import java.util.stream.Stream; // Program to reverse elements of a sequential stream in Java class Main { public static <T> Collector<T, List<T>, List<T>> reverse(long n) { return Collector.of(ArrayList::new, (list, element) -> { list.add(element); if (list.size() == n) { Collections.reverse(list); } }, (a, b) -> a); // dummy } public static void main(String[] args) { List<Integer> lists = Arrays.asList(1, 2, 3, 4, 5); Stream<Integer> stream = lists.stream(); int n = lists.size(); stream.collect(reverse(n)) .forEach(System.out::println); } } |
The above solution requires the count of elements in the stream in advance. We can avoid that by using ArrayDeque in place of an ArrayList, as demonstated below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import java.util.ArrayDeque; import java.util.stream.Collector; import java.util.stream.Stream; // Program to reverse elements of a sequential stream in Java class Main { public static <T> Stream<T> reverse(Stream<T> stream) { return stream.collect( Collector.of(() -> new ArrayDeque<T>(), ArrayDeque::addFirst, (a, b) -> a) // dummy ).stream(); } public static void main(String[] args) { Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); reverse(stream) .forEach(System.out::println); } } |
That’s all about reversing a Sequential Stream in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)