reversed()
Returns a reverse-ordered view of a list (Java 21) without copying, and how it differs from Collections.reverse.
default List<E> reversed()- Added in Java Java 21
Return value
List<E>A reverse-ordered view of this list. Changes to the original are visible in the view, and changes through the view, if the original allows them, go to the original.
Errors
The call itself does not throw. Mutating the view throws UnsupportedOperationException if the original list is unmodifiable.
reversed() arrived with sequenced collections in Java 21. It returns a List that presents the same elements in the opposite order. Nothing is copied and nothing is sorted: index 0 of the view is the last element of the original.
A live view
Because it is a view, it stays in step with the original list. Add an element to the original and it appears at the front of the reversed view. Write through the view and the change lands in the original, at the mirrored position: reversed().addFirst(x) appends x to the end of the original list.
If the original is unmodifiable, such as a List.of list, the view is unmodifiable too, and any change through it throws UnsupportedOperationException. Reading is always fine.
reversed() versus Collections.reverse
list.reversed()returns a new view and leaves the list as it is. It works on unmodifiable lists.Collections.reverse(list)reorders the list itself and returns void. It needs a modifiable list.list.stream().sorted(Comparator.reverseOrder())sorts descending, which is a different operation: it reorders by value, not by position.
Typical use
Event logs, audit trails and order histories are usually stored in the order they happened. Clients often want newest first. for (var e : history.reversed()) iterates backwards without index arithmetic, and history.reversed().subList(0, n) gives the newest n entries.
When you hand the result to a JSON serialiser or store it, remember it is a view backed by the original. If the original keeps changing, for example a shared in-memory log, take a copy with List.copyOf(list.reversed()) so the response reflects one moment in time.
Reversing twice gives you a list in the original order again; there is no need to undo a reversal by calling Collections.reverse.
Example
When to use it
- Returning an order's status history newest first in an API response.
- Showing the latest entries of an in-memory audit log on an admin page.
- Running shutdown or cleanup steps in the reverse order of start-up.
Frequently asked questions
How do I reverse a list in Java?
On Java 21 and later, list.reversed() returns a reversed view without changing the list. Collections.reverse(list) reverses a modifiable list in place on any version.
Does List.reversed() create a copy?
No. It returns a view backed by the original list, so later changes to either are visible in the other. Use List.copyOf(list.reversed()) for an independent copy.
More examples
View versus in-place reverse
reversed leaves the original alone. Collections.reverse changes the original, and the view, which mirrors it, flips back to ascending.
void main() {
List<Integer> nums = new ArrayList<>(List.of(1, 2, 3));
List<Integer> view = nums.reversed();
IO.println("view " + view + ", original " + nums);
Collections.reverse(nums);
IO.println("after Collections.reverse: " + nums);
IO.println("view now: " + view);
}
// Output:
// view [3, 2, 1], original [1, 2, 3]
// after Collections.reverse: [3, 2, 1]
// view now: [1, 2, 3]Newest n entries of a log
reversed plus subList picks the newest entries without sorting. List.copyOf freezes the slice so later log writes do not change the response.
record Event(int seq, String type) {}
void main() {
List<Event> log = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
log.add(new Event(i, i % 2 == 0 ? "login" : "view"));
}
int n = 3;
List<Event> latest = List.copyOf(log.reversed().subList(0, Math.min(n, log.size())));
latest.forEach(e -> IO.println(e.seq() + " " + e.type()));
}
// Output:
// 5 view
// 4 login
// 3 viewIterating backwards
Request middleware runs in order on the way in and in reverse on the way out. reversed gives the exit order without index loops.
void main() {
List<String> middleware = List.of("auth", "logging", "compression");
for (String m : middleware) {
IO.println("enter " + m);
}
for (String m : middleware.reversed()) {
IO.println("exit " + m);
}
}
// Output:
// enter auth
// enter logging
// enter compression
// exit compression
// exit logging
// exit auth
Discussion