1. Overview

When we work with Kotlin, we often work with lists. Sometimes, we need to reverse the order of elements in a list, for example, for processing the data in the reverse order, or for presentation purposes, and so on.

Kotlin provides two convenient methods to achieve this: reversed() and asReversed().

In this quick tutorial, we’ll explore these methods and understand their differences.

2. Introduction to the List.reversed() and the List.asReversed() Function

First, let’s see how to use reversed() and asReversed() through an example. For simplicity, we’ll use unit test assertions to verify results in this tutorial:

val inputList = listOf("item 1", "item 2", "item 3", "item 4", "item 5")
val expected = listOf("item 5", "item 4", "item 3", "item 2", "item 1")

val result1 = inputList.reversed()
val result2 = inputList.asReversed()

assertEquals(expected, result1)
assertEquals(expected, result2)

As the example above shows, the usage of these two functions is pretty straightforward. Both functions return the elements in the original list in the reversed order. 

However, they are different functions in Kotlin’s standard library. So next, let’s understand the differences between them.

3. The reversed() Function

First, let’s understand what the reversed() function does by checking its implementation:

public fun <T> Iterable<T>.reversed(): List<T> {
    if (this is Collection && size <= 1) return toList()
    val list = toMutableList()
    list.reverse()
    return list
}

As we can see, the reversed() function is available for Iterable objects and returns a read-only List. It internally creates a new MutableList object from the original list. Then, it reverses the elements of the mutable list and returns the mutable list as a read-only List. It’s worth noting that the List.reverse() in the code above is a function of MutableList. It performs in-place list reversal and returns Unit.

Further, the read-only list returned by reversed() won’t reflect the original list’s further changes. Let’s create a test to verify this:

val inputList = mutableListOf("item 1", "item 2", "item 3", "item 4", "item 5")
val expected = mutableListOf("item 5", "item 4", "item 3", "item 2", "item 1")

val result = inputList.reversed()
assertEquals(expected, result)

// add a new element to the input list:
inputList.add("LAST")
assertEquals(expected, result)

Next, let’s move to the asReversed() function to see if it behaves similarly.

4. The asReversed() Function

Again, let’s first have a look at the asReversed() function’s signature:

public fun <T> MutableList<T>.asReversed(): MutableList<T>

From the function definition, we can see two differences compared to the reversed() function:

  • asReversed()* is only available for *MutableList. On the other hand, reversed() is an extension function of Iterable.
  • The asReversed() function returns a MutableList instead of a read-only List

Next, let’s create a test to examine whether asReversed()’s result reflects the changes of the original MutableList:

val inputList = mutableListOf("item 1", "item 2", "item 3", "item 4", "item 5")
val expected = mutableListOf("item 5", "item 4", "item 3", "item 2", "item 1")

val result = inputList.asReversed()
assertEquals(expected, result)

// append a new element to the input list, the result list reflects the changes
inputList.add("LAST")
val expectedAfterChanges = mutableListOf("LAST", "item 5", "item 4", "item 3", "item 2", "item 1")
assertEquals(expectedAfterChanges, result)

// append a new element to the reversed list (result) , the change is reflected in the original list (inputList):
result.add("FIRST")
assertEquals(listOf("FIRST", "item 1", "item 2", "item 3", "item 4", "item 5", "LAST"), inputList)

As we can see, we first performed the same test on the asReversed() function, and it turns out that asReversed()’s result reflects the changes in the original inputList.

In this article, we explored through examples two functions to reverse a list in Kotlin: reversed() and asReversed().

The reversed() function returns a new read-only view with elements in reverse order without modifying the original list. Further, it doesn’t reflect the further changes applied to the original input list.

On the other hand, asReversed() creates a mutable view. This reversed view reflects the changes in the original list and vice versa.

As usual, all code snippets presented here are available over on GitHub.