1. Overview

We often encounter situations where we need to randomly shuffle the elements of a list.

In this quick tutorial, we’ll explore various techniques to shuffle a list in Kotlin.

2. Introduction to the Problem

Shuffling a list isn’t a hard job, as Kotlin provides shuffling functions. However, there are two kinds of Lists in Kotlin, read-only and mutable lists. Furthermore, the behavior of shuffling functions can vary depending on the parameters they receive or the type of lists they are applied to. We may get unexpected results if we don’t understand those shuffling functions well.

Therefore, this tutorial will address the shuffling functions in the Kotlin standard library. Also, we’ll cover the read-only and mutable lists.

So next, let’s learn how to master the art of shuffling!

3. Shuffling a Read-Only List

First of all, let’s initialize a read-only list using the range expression:

val readOnlyList = ('A'..'Z').toList()

Now, we have a list of 26 uppercase Chars of English letters in order.

Kotlin can shuffle a read-only list with two functions: shuffled() and shuffled(random: Random).

Next, let’s see how to use them.

The usage of the shuffled() function is pretty straightforward:

val result = readOnlyList.shuffled()
println(
  """
      |Before Shuffling:
      |$readOnlyList
      |Shuffled result:
      |$result""".trimMargin()
)

As the example above shows, to shuffle a read-only list, we call theList.shuffled(). We used raw string and trimMargin() for a better output layout:

Before Shuffling:
[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
Shuffled result:
[P, G, K, E, T, N, O, I, M, Q, C, B, U, F, A, V, Y, Z, J, H, W, S, X, D, R, L]

As the output shows, the list is shuffled randomly. Further, as shuffled() is based on Random, it produces a different result every time we call it, for example:

val shuffleResults = listOf(
  readOnlyList.shuffled(),
  readOnlyList.shuffled(),
  readOnlyList.shuffled(),
)
assertEquals(3, shuffleResults.distinct().size)

However, in some circumstances, we want to randomly shuffle the list using a specified random instance as the source of randomness. Then, we can use the shuffled(random: Random) function with a Random instance as the argument.

When we use this function, it’s important to note that the random instances initialized from the same seed value generate the same random number sequence. Thus, if we use these random instances for the shuffled(random) function, the shuffled result can be the same:

val myRandomSeed = 42
val shuffleResults = listOf(
  readOnlyList.shuffled(Random(myRandomSeed)),
  readOnlyList.shuffled(Random(myRandomSeed)),
  readOnlyList.shuffled(Random(myRandomSeed)),
)
assertEquals(1, shuffleResults.distinct().size)

4. Shuffling a MutableList

Now, let’s look at how to shuffle a mutable list. Same as read-only lists, both shuffled() and shuffled(random: Random) are available for mutable lists, for example:

val result = mutableList.shuffled()
println(
  """
      |Before Shuffling:
      |$readOnlyList
      |Shuffled result:
      |$result""".trimMargin()
)

The code above produces this output:

Before Shuffling:
[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
Shuffled result:
[D, G, I, U, A, K, L, T, H, E, S, X, Q, W, Z, V, Y, J, F, C, B, N, M, P, R, O]

Additionally, mutable lists can perform in-place shuffling through the shuffle() function:

mutableList.shuffle()
println(
  """The original list:
  |$mutableList""".trimMargin()
)

As we can see, calling shuffle() will shuffle the original mutable list:

The original list:
[R, X, W, Q, V, S, M, J, T, F, U, H, Y, E, B, L, O, I, A, K, C, G, N, Z, P, D]

Also, we can pass a random instance to shuffle() to perform in-place shuffling with a custom source of randomness.

5. Conclusion

In this quick article, we explored shuffling a list in Kotlin. We can use shuffled() and shuffled(random: Random) to shuffle a read-only or mutable list. Additionally, mutable lists can be shuffled in-place by the shuffle() function.

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

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.