Reversing a list or an ArrayList means putting the last element at first position, second last element at second position and finally, placing the first element as the last.
This article will show you various ways in which a list can be reversed in java with example programs.
1. Using Collections.reverse()
java.util.Collections
class has a reverse()
method which accepts a List argument and reverses the order of its elements.
It is a static method and thus can be invoked directly by using the class name.
import java.util.List; import java.util.ArrayList; import java.util.Collections; public class ReverseListUsingCollections { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); Collections.reverse(list); System.out.println("After reversing..."); System.out.println(list); } }
Output of above example is
Before reversing…
Google, Facebook, Youtube, Whatsapp, Instagram
After reversing…
Instagram, Whatsapp, Youtube, Facebook, Google
which shows that the list items are reversed.
2. Reversing by iterating and removing
In this method, you iterate over the list, remove an item from the end and add it to the beginning.
Both these operations are performed on the same list.
Following algorithm will reverse the list elements.
- Use a
for
loop to iterate over the list with two different counters: one from the beginning and one from the end of the list. - Remove element at the position of second counter and insert it at the position of first counter.
- In every iteration, increment the first counter and while the second counter is fixed at the last element.
- Continue iteration till first counter is lesser than the second one because when this happens, all the list elements have been covered.
Example program written on this algorithm is given below.
import java.util.List; import java.util.ArrayList; public class ReverseListUsingIteration { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // iterate over the list for (int i = 0, j = list.size() - 1; i < j; i++) { // remove element from end and add it to beginning String endElement = list.remove(j); list.add(i, endElement); } System.out.println("After reversing..."); System.out.println(list); } }
Notice the counter variables in for
loop.
One starts from the beginning and is incremented in every iteration while second remains fixed.
In first iteration, last element is removed and inserted at 0 index.
Now, second last element becomes the last element.
In second iteration, again the last element(which was second last element before the previous iteration) is removed and inserted at index 1.
This will continue till the first counter becomes equal to the second counter.
Output is
Before reversing…
Google, Facebook, Youtube, Whatsapp, Instagram
After reversing…
Instagram, Whatsapp, Youtube, Facebook, Google
3. Using iteration
This is a traditional and simplest method to reverse a list and comprises of following steps:
- Create an empty list.
- Iterate over the list from end to beginning.
- In every iteration, fetch the current element and add it to the new list.
- After the iteration completes, the new list will have the elements in reverse order.
Example,
public class ReverseUsingIteration { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // create an empty list List reverseList = new ArrayList<>(); // iterate from end to beginning for(int i = list.size() - 1; i >=0; i--) { // get current element String element = list.get(i); // add it to the new list reverseList.add(element); } System.out.println("After reversing..."); System.out.println(reverseList); } }
4. Using ListIterator
A java.util.ListIterator
is used for iterating over a list.
It is different from a conventional java iterator in that it can also be used to iterate in reverse direction, that is, from last element till first.
This feature of a ListIterator
will be used to reverse a list. Example,
public class ReverseListUsingIterator { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // create an empty list List reverseList = new ArrayList<>(); // initialize a list iterator at the end element ListIterator listIterator = list.listIterator(list.size()); // iterate in previous direction while(listIterator.hasPrevious()) { // get previous element String element = listIterator.previous(); // insert it into new list reverseList.add(element); } System.out.println("After reversing..."); System.out.println(reverseList); } }
Following points should be understood about the above program.
- An object of
java.util.ListIterator
can be created by callinglistIterator()
method on the list object. - There are two versions of
listIterator()
method.
The one used in the example takes an integer argument which is the index of element at which the iterator will be positioned initially. - The example supplies the size of the list to the
listIterator()
method so that it is positioned after the last list element. ListIterator
contains ahasPrevious()
method which returnstrue
if the list contains an element before the current iterator position.hasPrevious()
can be used to iterate over the list in reverse direction, that is, starting from the last element to the first.- In every iteration, the current list element is retrieved using iterator’s
previous()
method, which returns the element before the current iterator’s position. - This element is then inserted into the new list.
Thus, after the iterator completes, the new list will have all the elements inserted into the reverse order.
Output of the program is
Before reversing…
Google, Facebook, Youtube, Whatsapp, Instagram
After reversing…
Instagram, Whatsapp, Youtube, Facebook, Google
5. Using recursion
A recursive method can also be used to reverse a list. In this method, remove the first element and call this method again recursively.
After the recursive call, add element to the list.
Recursive method is called till the list becomes empty. Example,
public class ReverseListUsingRecursion { /* * Recursive method to reverse a list */ static void reverse(List list) { // check if list is empty if (list.size() == 0) { return; } // remove first element String element = list.remove(0); // call this method again reverse(list); // add element to the list list.add(element); } public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // call recursive method reverse(list); System.out.println("After reversing..."); System.out.println(list); } }
In every recursive call, the first element is removed from the list.
When the list becomes empty, all recursive calls start returning and the element removed from the list is now added to the empty list in reverse order, that is, the element that was removed at last is added first.
6. Using guava library
Guava library has a com.google.common.collect.Lists
class which contains a static reverse()
method. reverse()
accepts a List as argument and returns a List with its contents reversed.
Example,
public class ReverseUsingGuava { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // reverse list List rList = Lists.reverse(list); System.out.println("After reversing..."); System.out.println(rList); } }
Output is
Before reversing…
Google, Facebook, Youtube, Whatsapp, Instagram
After reversing…
Instagram, Whatsapp, Youtube, Facebook, Google
There is one problem with the above code.reverse
method returns a new List which is backed by the original list.
This means that any changes done to the returned list will also be made to the original list.
Thus, if you add a new element to the list returned by reverse
method, then it will also be added to the original list.
To avoid this, create a new list with the contents of the list returned by the reverse
method. That is,
List rList = new ArrayList<>(Lists.reverse(list));
7. Using Java 8
Java 8 streams provide a new way of reversing a List by using the following example.
public class ReverseUsingJava8 { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // create empty list List rList = new ArrayList<>(); list.stream().collect(Collectors. toCollection(LinkedList :: new)). descendingIterator(). forEachRemaining(rList :: add); System.out.println("After reversing..."); System.out.println(rList); } }
In this example, the statement
list.stream().collect(Collectors.toCollection(LinkedList :: new)).descendingIterator()
.forEachRemaining(rList :: add);
reverses the list.
This statement can be broken into following sub-statements to understand it better
1. list.stream(): Returns a stream over the specified list.
2. collect(Collectors.toCollection(LinkedList :: new)): collect
method is used to accumulate the elements of a collection into another one.
Here, we supply a new collection to the collect method using Collectors.toCollection
method. Collectors.toCollection
returns a new collection object.
In this example, the new collection is a java.util.LinkedList
which we supply using a new
operator.
3. descendingIterator().forEachRemaining(rList :: add): Calling descendingIterator()
method on the new collection(which is a LinkedList) in this example returns an iterator in reverse order.forEachRemaining()
method performs an action on the elements of the collection.
In this example, the action is to add the element to the new list(rList).
8. Using Java 8
This method performs reverse iteration of the list using java 8 streams as shown below.
public class ReverseUsingJava8 { public static void main(String[] args) { // create an empty list to reverse List list = new ArrayList<>(); // add elements list.add("Google"); list.add("Facebook"); list.add("Youtube"); list.add("Whatsapp"); list.add("Instagram"); System.out.println("Before reversing..."); System.out.println(list); // reverse iterate a list List rList = IntStream.range(0, list.size()). map(i -> list.size() - 1 - i).mapToObj(list::get). collect(Collectors.toList()); System.out.println("After reversing..."); System.out.println(rList); } }
In the above example, the below statement does the list reverse operation.
IntStream.range(0, list.size()).map(i -> list.size() – 1 – i).mapToObj(list :: get)
.collect(Collectors.toList());
This statement can be broken into following sub-statements to understand it better.
1. IntStream.range(0, list.size())
Returns a stream of integers starting from the index represented by the first argument till the second argument.
Here, we take the first index as 0 and the last index as the size of list.
2. map(i -> list.size() – 1 -i)map()
method returns a stream after applying the operation supplied as argument to this method.
Here, we supply the index of the list in reverse direction decreasing it by 1 every time.
3. mapToObj(list :: get)mapToObj()
method performs an operation over its stream. The operation is supplied as an argument to this method.
Here, the operation is fetching each element of the list.
4. collect(Collectors.toList())
Finally after applying all these operations, collect the stream elements to a new list.
All the above statements when combined perform an operation on the list indexes(which are from 0 to size of list), map each index to an index in the reverse direction, fetch list element at that index and add them to another list.
Output of this program is
Before reversing…
[Google, Facebook, Youtube, Whatsapp, Instagram]After reversing…
[Instagram, Whatsapp, Youtube, Facebook, Google]
9. reversed() java 21
Java 21 introduced sequenced collections where a new interface SequencedCollection
is added.
SequencedCollection
has a reversed() method which reverses the collection. Since java.util.List
extends SequencedCollection
, you can directly call reversed()
method to reverse a list. Example,
List<String> list = List.of("A","B", "C"); List<String> reversed = list.reversed(); System.out.println(reversed); // [C, B, A]
Hope this article was useful for learning different ways in which a list can be reversed in java.