Reputation: 5457
What is the simplest way to reverse this ArrayList?
ArrayList<Integer> aList = new ArrayList<>();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
while (aList.listIterator().hasPrevious())
Log.d("reverse", "" + aList.listIterator().previous());
Upvotes: 381
Views: 430354
Reputation: 11060
2023 Edition for Kotlin
asReversed
Returns a reversed read-only view of the original List. All changes made in the original list will be reflected in the reversed one.
val original = mutableListOf('a', 'b', 'c', 'd', 'e')
val originalReadOnly = original as List<Char>
val reversed = originalReadOnly.asReversed()
println(original) // [a, b, c, d, e]
println(reversed) // [e, d, c, b, a]
// changing the original list affects its reversed view
original.add('f')
println(original) // [a, b, c, d, e, f]
println(reversed) // [f, e, d, c, b, a]
original[original.lastIndex] = 'z'
println(original) // [a, b, c, d, e, z]
println(reversed) // [z, e, d, c, b, a]
reversed
Returns a list with elements in reversed order.
val myList = listOf(1, 2, 3)
println(myList.reversed()) // [3, 2, 1]
Upvotes: -1
Reputation: 12849
As of Java 21 you can use ArrayList#reversed()
. Where ArrayList
implements SequencedCollection
.
This is part of Sequenced Collections added to the Collections framework.
Upvotes: 6
Reputation: 14618
Kotlin Users
val reverse: List<Int> = list.reversed();
Happy Coding!
Upvotes: 1
Reputation: 2415
We can also do the same using java 8.
public static<T> List<T> reverseList(List<T> list) {
List<T> reverse = new ArrayList<>(list.size());
list.stream()
.collect(Collectors.toCollection(LinkedList::new))
.descendingIterator()
.forEachRemaining(reverse::add);
return reverse;
}
Upvotes: 3
Reputation: 693
Solution without using extra ArrayList or combination of add() and remove() methods. Both can have negative impact if you have to reverse a huge list.
public ArrayList<Object> reverse(ArrayList<Object> list) {
for (int i = 0; i < list.size() / 2; i++) {
Object temp = list.get(i);
list.set(i, list.get(list.size() - i - 1));
list.set(list.size() - i - 1, temp);
}
return list;
}
Upvotes: 6
Reputation: 11116
Reversing a ArrayList in a recursive way and without creating a new list for adding elements :
public class ListUtil {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
arrayList.add("4");
arrayList.add("5");
System.out.println("Reverse Order: " + reverse(arrayList));
}
public static <T> List<T> reverse(List<T> arrayList) {
return reverse(arrayList,0,arrayList.size()-1);
}
public static <T> List<T> reverse(List<T> arrayList,int startIndex,int lastIndex) {
if(startIndex<lastIndex) {
T t=arrayList.get(lastIndex);
arrayList.set(lastIndex,arrayList.get(startIndex));
arrayList.set(startIndex,t);
startIndex++;
lastIndex--;
reverse(arrayList,startIndex,lastIndex);
}
return arrayList;
}
}
Upvotes: 2
Reputation: 71
ArrayList<Integer> myArray = new ArrayList<Integer>();
myArray.add(1);
myArray.add(2);
myArray.add(3);
int reverseArrayCounter = myArray.size() - 1;
for (int i = reverseArrayCounter; i >= 0; i--) {
System.out.println(myArray.get(i));
}
Upvotes: 7
Reputation: 355
The trick here is defining "reverse". One can modify the list in place, create a copy in reverse order, or create a view in reversed order.
The simplest way, intuitively speaking, is Collections.reverse
:
Collections.reverse(myList);
This method modifies the list in place. That is, Collections.reverse
takes the list and overwrites its elements, leaving no unreversed copy behind. This is suitable for some use cases, but not for others; furthermore, it assumes the list is modifiable. If this is acceptable, we're good.
If not, one could create a copy in reverse order:
static <T> List<T> reverse(final List<T> list) {
final List<T> result = new ArrayList<>(list);
Collections.reverse(result);
return result;
}
This approach works, but requires iterating over the list twice. The copy constructor (new ArrayList<>(list)
) iterates over the list, and so does Collections.reverse
. We can rewrite this method to iterate only once, if we're so inclined:
static <T> List<T> reverse(final List<T> list) {
final int size = list.size();
final int last = size - 1;
// create a new list, with exactly enough initial capacity to hold the (reversed) list
final List<T> result = new ArrayList<>(size);
// iterate through the list in reverse order and append to the result
for (int i = last; i >= 0; --i) {
final T element = list.get(i);
result.add(element);
}
// result now holds a reversed copy of the original list
return result;
}
This is more efficient, but also more verbose.
Alternatively, we can rewrite the above to use Java 8's stream
API, which some people find more concise and legible than the above:
static <T> List<T> reverse(final List<T> list) {
final int last = list.size() - 1;
return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list
.map(i -> (last - i)) // reverse order
.mapToObj(list::get) // map each index to a list element
.collect(Collectors.toList()); // wrap them up in a list
}
nb. that Collectors.toList()
makes very few guarantees about the result list. If you want to ensure the result comes back as an ArrayList, use Collectors.toCollection(ArrayList::new)
instead.
The third option is to create a view in reversed order. This is a more complicated solution, and worthy of further reading/its own question. Guava's Lists#reverse method is a viable starting point.
Choosing a "simplest" implementation is left as an exercise for the reader.
Upvotes: 25
Reputation: 24157
Just in case we are using Java 8, then we can make use of Stream. The ArrayList is random access list and we can get a stream of elements in reverse order and then collect it into a new ArrayList
.
public static void main(String[] args) {
ArrayList<String> someDummyList = getDummyList();
System.out.println(someDummyList);
int size = someDummyList.size() - 1;
ArrayList<String> someDummyListRev = IntStream.rangeClosed(0,size).mapToObj(i->someDummyList.get(size-i)).collect(Collectors.toCollection(ArrayList::new));
System.out.println(someDummyListRev);
}
private static ArrayList<String> getDummyList() {
ArrayList dummyList = new ArrayList();
//Add elements to ArrayList object
dummyList.add("A");
dummyList.add("B");
dummyList.add("C");
dummyList.add("D");
return dummyList;
}
The above approach is not suitable for LinkedList as that is not random-access. We can also make use of instanceof
to check as well.
Upvotes: 1
Reputation: 34765
Collections.reverse(aList);
Example (Reference):
ArrayList aList = new ArrayList();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
Collections.reverse(aList);
System.out.println("After Reverse Order, ArrayList Contains : " + aList);
Upvotes: 895
Reputation: 117
Another recursive solution
public static String reverse(ArrayList<Float> list) {
if (list.size() == 1) {
return " " +list.get(0);
}
else {
return " "+ list.remove(list.size() - 1) + reverse(list);
}
}
Upvotes: -1
Reputation: 5471
A little more readable :)
public static <T> ArrayList<T> reverse(ArrayList<T> list) {
int length = list.size();
ArrayList<T> result = new ArrayList<T>(length);
for (int i = length - 1; i >= 0; i--) {
result.add(list.get(i));
}
return result;
}
Upvotes: 0
Reputation: 1286
Not the simplest way but if you're a fan of recursion you might be interested in the following method to reverse an ArrayList:
public ArrayList<Object> reverse(ArrayList<Object> list) {
if(list.size() > 1) {
Object value = list.remove(0);
reverse(list);
list.add(value);
}
return list;
}
Or non-recursively:
public ArrayList<Object> reverse(ArrayList<Object> list) {
for(int i = 0, j = list.size() - 1; i < j; i++) {
list.add(i, list.remove(j));
}
return list;
}
Upvotes: 22