In this tutorial, we will learn how we can reverse a list in Java. Reversing a list means putting the first element of the list at the last position, the second element at the second last position and finally putting the last element at the first position. There are majorly 7 ways, using which we can reverse a list. Before diving into those methods, let us have a quick recap of lists and the methods that we will be discussing in this article.
What is a List in Java?
Till now we are familiar with the concept of arrays. An array is a group of elements with similar data types stored in contiguous memory locations referenced under a single name. List are essentially just like an array except their size can grow or shrink during the runtime. This change in the size of a list during runtime is called dynamic nature. If we try to access or add any element beyond the size of an array then we get an exception. However, this is not the case with lists. When we add an element to a list then its size increases by one and whenever we remove an element from a list its size decreases by one. So technically we can define a list as a dynamic array. A technical note here is that List is an interface in java. So, in order to create its object, we have to use classes that implement this interface like ArrayList.
Let's look at two methods of lists that we will be using throughout this article
1) List.add()
This method adds a specified value at the specified location in the list. The syntax of the List_add() method is given below:
void add(int index, E element)
As a result of adding an element to the list, this method shifts the element currently at that position (if any) and any subsequent elements to the right.
2) List.remove()
This method removes an element at the specified position in the list. The method syntax is as follows:
E remove(int index)
Due to the removal of an element from the list, any subsequent elements are shifted to the left. This method returns the element which was removed is removed from the list.
For example:
import java.util.*; public class FavTutor{ public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add(0, "I"); list.add(1, "Love"); list.add(2, "Favtutor"); System.out.println("List before removal:"); System.out.println(list); list.remove(1); System.out.println("List after removal:"); System.out.println(list); } }
Output:
List before removal: [I, Love, Favtutor] List after removal: [I, Favtutor]
How to Reverse a List in Java?
While programming in java, there might be a scenario where you wish to reverse the order of the list. Reversing a list is a conventional part of any programming language and therefore, let us discuss 7 explicit methods by which you can reverse a list in java efficiently. Note that a List reversal method can be categorized as either inplace or not inplace. An inplace conversion means that the conversion should take place without using any auxiliary list, by overwriting the existing elements of the specified list.
1) Using Collections.reverse() method
It is the most straightforward way to reverse a list in java. The java.util.Collections class contains the reverse() method which can be used to reverse the order of the elements in the specified list. The reverse method takes the given list to reverse as a method parameter and returns the final reversed list as output. The approach considers inplace conversion which means that conversion takes place in the list itself which was passed as the argument. The method syntax is as follows:
public static void reverse(List<?> list)
Since this is a static method, it can be invoked directly using the class name. This method throws a UnsupportedOperationException if the list passed is immutable.
For example:
import java.util.*; import java.util.Collections; public class FavTutor{ public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); System.out.println("Before reversing:"); System.out.println(clothes); Collections.reverse(clothes); System.out.println("After reversing:"); System.out.println(clothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
2) Using List.add() with List.remove() method
In this approach, we iterate through the list, and by using a combination of List.add() and List.remove() methods we reverse the list in java. As discussed in the above section, the List.add() method adds an element at the desired location in the list at the same time, the List.remove() method removes an element from the list. This approach of list reversal is also inplace of conversation and hence the operation takes place in the list itself.
To reverse a list using this approach, we first iterate through the list. In each iteration, we remove the last element from the list and add it to the front of the list.
Let us look at the algorithm of this approach to understand it better.
Use a for loop to iterate over the list using two different counter variables: the first variable points to the beginning of the list and the second variable points to the end of the list. Remove the element from the position pointed by the second counter Add the element removed to the position pointed by the first counter. Increment the first counter The for loop continues till the first counter is smaller than the second counter.
When both the counter become equal then all the elements in the list are covered and hence the loop terminates
For example:
import java.util.*; import java.util.Collections; public class FavTutor{ public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); System.out.println("Before reversing:"); System.out.println(clothes); for( int i = 0, j = clothes.size() - 1; i < j; i++){ String tempClotheString = clothes.remove(j); clothes.add(i, tempClotheString); } System.out.println("After reversing:"); System.out.println(clothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
Let us focus on this statement in the code. Notice the counter variables.
The first counter(i) starts from the beginning of the list. It is incremented in every iteration.
The second counter (j) remains fixed to the last of the list.
Let us now look at the working of this approach using some images. We will use the same list from the code.
In the first iteration, i = 0 and j = 3. We remove the last element, from the 3rd index, which is also the position pointed by the counter j. Later add this element at the position referred by counter i, 1st index. The addition of an element leads to the shifting of elements in front of it. Finally, the value of the i counter is incremented by 1.
In the second iteration, i = 1 and j = 3. We again remove the last element from the list, pointed by the j counter. Later, add this element at the position referred by counter i, 2nd index. The element which was originally present at the 2nd position and all the elements subsequent to it shifts to the right, as shown in the image. At the end of this iteration, the value of i is increased by 1.
In the third iteration, i = 2 and j = 3. The last element is removed from the list. The removed element is added at the position referred by counter i, 3rd index. The element which was present at the 3rd position now shifts to the 4th position.
The counter i is incremented and becomes equal to 4. The looping condition is tested, i
3) Using recursion
In this method, we create a recursive function that removes the first element from the list and then makes a recursive call to itself. When the recursive call returns, the removed element is added again to the list. You may be wondering how will this approach lead to the reversal of a list. To understand this let us first look at the code for this approach.
For example:
import java.util.*; import java.util.Collections; public class FavTutor{ static void reverseList(List<String> l){ if(l.size() == 0){ return; } else{ String element = l.remove(0); reverseList(l); l.add(element); } } public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); System.out.println("Before reversing:"); System.out.println(clothes); reverseList(clothes); System.out.println("After reversing:"); System.out.println(clothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
Let us understand how this function works to reverse the list in java. In each recursion, we are removing an element from the list. When the list becomes empty and the recursion call starts to return, the element which was removed in the last is added first to the list. Later, the same process is repeated and the second last element removed is added to the list. In this way, the element which was removed first is added in the last and the resulted list is now reversed.
4) Using iteration
This approach for reversing the list is not inplace method and therefore the reversed list is stored in different List objects. This method is also much simpler to implement and understand than some of the methods discussed above. Here, we create a new list and iterate through the original list from end to beginning. In every iteration, remove the element at the index referred by the counter and add it to the new list. When the loop terminates, the new list contains the elements of the original list in reverse order.
For example:
import java.util.*; public class FavTutor{ public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); List<String> reverseClothes = new ArrayList<>(); for( int i = clothes.size()-1; i >= 0; i--){ String element = clothes.get(i); reverseClothes.add(element); } System.out.println("Before reversing:"); System.out.println(clothes); System.out.println("After reversing:"); System.out.println(reverseClothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
5) Using ListIterator
Java has an Iterator class, whose objects can be used to iterate over different collections. Just like that Java also has a ListIterator class which enables you to iterate over a list. This approach of reversing a list is just like the previous approach, except that here we are using a ListIterator object to loop through the list instead of a counter variable. This is also not an inplace method. Let us first understand a few methods of this class that will be used to reverse a list in java.
ListIterator.hasPrevious()- This method returns true if the list contains an element before the current iterator position
ListIterator.previous()- This method returns the element before the current iterator’s position
To create an object of this class, we need to use the ListIterator() function of the List class. This function takes an integer argument which is the index at which the iterator will be positioned initially
Let's discuss this approach in detai0 below.
First, create a ListIterator object using the ListIterator() function and pass the list size as its argument. This results in the ListIterator being positioned after the last list element. Later, iterate over the list using a while loop. The condition of this loop checks if an element is present in the list using the hasPrevious() method. If an element is present before the iterator, then fetch that element using the previous() method. The fetched element is then added to a new list. Note that the loop is going from the last element to the first element with the help of the ListIterator object. When the loop terminates, the new list contains the reversed list.
For example:
import java.util.*; public class FavTutor{ public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); List<String> reverseClothes = new ArrayList<>(); ListIterator<String> listIterator = clothes.listIterator(clothes.size()); while(listIterator.hasPrevious()){ String elemenString = listIterator.previous(); reverseClothes.add(elemenString); } System.out.println("Before reversing:"); System.out.println(clothes); System.out.println("After reversing:"); System.out.println(reverseClothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
6) Using guava library
Java contains a large collection of libraries and the guava library is one of them. The Lists class of this library possesses the reversed() method which can help you to reverse the list efficiently. The reverse method is a static method, therefore we can call it directly using the class name. This method takes a list as its argument and returns a new reversed list. So this approach is also not an inplace approach.
For example:
public class FavTutor{ public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); System.out.println("Before reversing:"); System.out.println(clothes); List reverseClothes = Lists.reverse(clothes); System.out.println("After reversing:"); System.out.println(reverseClothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
There is a major issue with this approach, i.e., the new list returned by the reverse method is backed up by the original list. It means that we change the reversed list, then the original list will also be affected. To get around this problem, we can create a new list containing the contents of the list returned by the reverse method.
7) Using Java 8 stream API
This approach makes use of the stream API. First, create a stream of integers representing the indexes of the list. The stream is created using the IntStream.range(0, list.size()). This method returns a stream containing all the integers between the range 0 (inclusive) and the size of the list (Exclusive). Using the map() operation, we map the stream containing the indices in such a way that indices are reversed.
For example, the size of our list is 4, then the 0th index will become 4. So if our stream is 1,2,3,4, then the map function should become 4,3,2,1. Note that the map operation returns a stream after applying the operation, supplied as an argument, to each of the stream’s elements. We then use the maptToObj method. This method performs an operation, provided as the argument, over its stream. Pass the get operation as the argument which results in fetching elements from the list corresponding to the indices in the stream. Finally, apply the collect(Collectors.toList) to collect the stream elements to a new list.
For example:
import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; public class FavTutor{ public static void main(String[] args) { List<String> clothes = new ArrayList<>(); clothes.add("T-shirt"); clothes.add("Pants"); clothes.add("Socks"); clothes.add("Shoes"); System.out.println("Before reversing:"); System.out.println(clothes); List reverseClothes = IntStream.range(0, clothes.size()).map(i -> clothes.size() - 1- i).mapToObj(clothes::get).collect(Collectors.toList()); System.out.println("After reversing:"); System.out.println(reverseClothes); } }
Output:
Before reversing: [T-shirt, Pants, Socks, Shoes] After reversing: [Shoes, Socks, Pants, T-shirt]
Conclusion
While coding, there are several situations where we may want to reverse a list. Knowing how to reverse a list in any language is a skill that every coder must possess. But If you are a programmer and need java online help, then you can get in touch with us.
In this article, we saw how we can reverse a list using inbuilt methods as well as through naïve approaches. Each approach comes with its pros and cons which are thoroughly discussed above. It is highly recommended to understand these approaches while programming in java.