Reverse an ArrayList in Java in 5 different ways
In the previous post, we have discussed how to in-place reverse a list in Java. This post will discuss how to reverse an ArrayList in Java by creating a copy of it in reverse order without altering the ordering of elements in the original list. The specified list may or may not be mutable, but the returned list should be mutable.
1. Using Guava Library
Guava’s Lists.reverse() method creates a view of the specified list in reversed order. Since the original list backs the returned list, changes in the returned list are reflected in this list and vice-versa.
We can avoid this by creating a new ArrayList instance from the returned list, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.Arrays; import java.util.List; // Program to reverse an `ArrayList` in Java class Main { public static<T> List<T> reverseList(List<T> list) { return new ArrayList<>(Lists.reverse(list)); } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
2. Using Collections.reverse() method
We know that the Collections.reverse() method modifies the list in-place. The idea is to create a copy of the original list and then call the reverse() method on the copy rather than the original list.
|
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.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; // Program to reverse an `ArrayList` in Java class Main { public static<T> List<T> reverseList(List<T> list) { List<T> reverse = new ArrayList<>(list); Collections.reverse(reverse); return reverse; } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
Here’s is another way in Java 8 and above that uses Collections.reverse() along with Stream, and Collectors.collectingAndThen() method, which collects elements in the reversed 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 |
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; // Program to reverse an `ArrayList` in Java class Main { public static<T> List<T> reverseList(List<T> list) { return list.stream() .collect(Collectors.collectingAndThen( Collectors.toCollection(ArrayList::new), lst -> { Collections.reverse(lst); return lst.stream(); } )).collect(Collectors.toCollection(ArrayList::new)); } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
3. Using Java 8
We can also use Java 8 Stream to reverse a list. The idea is to get a stream of all valid indices of the list in reverse order and map each index to its value in the list, and finally collect the elements in an ArrayList.
|
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 |
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.ArrayList; // Program to reverse an `ArrayList` in Java class Main { public static<T> List<T> reverseList(List<T> list) { return IntStream.range(0, list.size()) .map(i -> (list.size() - 1 - i)) // IntStream .mapToObj(list::get) // Stream<T> .collect(Collectors.toCollection(ArrayList::new)); } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
Here’s even shorten version of the above utility method:
|
1 2 3 4 5 6 |
public static <T> List<T> reverseList(List<T> list) { return IntStream.range(0, list.size()) .mapToObj(i -> list.get(list.size() - 1 - i)) .collect(Collectors.toCollection(ArrayList::new)); } |
4. Extending AbstractList Class
AbstractList class provides a skeletal implementation of the List interface. The idea is to extend this class and provide implementations for the get(), set(), remove(), etc. methods, which should behave like a reversed list.
|
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; // Program to reverse an `ArrayList` in Java class Reverse<T> extends AbstractList<T> { private List<T> list; // Constructor private Reverse(List<T> list) { // create a new instance so that the original list remains unaffected this.list = new ArrayList<>(list); } public static <T> List<T> reverseList(List<T> list) { return new Reverse<>(list); } @Override public T get(int i) { return list.get(size() - 1 - i); } @Override public int size() { return list.size(); } @Override public boolean add(T e) { list.add(0, e); return true; } @Override public T set(int index, T element) { return list.set(size() - 1 - index, element); } @Override public void add(int index, T element) { list.add(size() - 1 - index, element); } @Override public T remove(int index) { return list.remove(size() - 1 - index); } // Override other util methods } class Main { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = Reverse.reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
5. Naive solution
Finally, this post is incomplete without discussing naive ways to reverse the list. The basic idea is to create an empty ArrayList and add elements of the original list to it by iterating the list in reverse order.
⮚ Java 8 – descendingIterator()
The idea is to accumulate elements of the given list into a LinkedList using Stream. Then we get an iterator over the elements in the LinkedList in reverse sequential order using LinkedList.descendingIterator() method and process each element using forEachRemaining() method:
|
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 |
import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; class Main { public static<T> List<T> reverseList(List<T> list) { List<T> reverse = new ArrayList<>(list.size()); new LinkedList<>(list) .descendingIterator() .forEachRemaining(reverse::add); return reverse; } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
⮚ List.listIterator()
Here, the idea is to use a ListIterator to iterate list 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 |
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.ListIterator; // Program to reverse an `ArrayList` in Java class Main { public static<T> List<T> reverseList(List<T> list) { List<T> reverse = new ArrayList<>(list.size()); ListIterator<T> itr = list.listIterator(list.size()); while (itr.hasPrevious()) { reverse.add(itr.previous()); } return reverse; } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
⮚ For loop
We can also iterate the list in reverse order using a simple for-loop, 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 25 26 |
import java.util.ArrayList; import java.util.Arrays; import java.util.List; // Program to reverse an `ArrayList` in Java class Main { public static<T> List<T> reverseList(List<T> list) { List<T> reverse = new ArrayList<>(list.size()); for (int i = list.size() - 1; i >= 0; i--) { reverse.add(list.get(i)); } return reverse; } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> reverse = reverseList(list); System.out.println(reverse); } } |
Output:
[5, 4, 3, 2, 1]
That’s all about reversing an ArrayList 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 :)