1. Overview
One of the most popular operations in collection structures such as List is to obtain a random item from the contained elements. Although it’s a simple operation, sometimes it may not be an obvious thing to implement.
In this tutorial, we’ll see some efficient implementations to do this in different contexts using Kotlin.
2. Implementation
The base concept of picking a random item from a list is to generate a random index to fetch the specific element using the List.get() method.
2.1. Single Random Item
As we mentioned, we need first to generate the random index and then get the element from the list:
fun randomElementFromGivenList() {
val list = listOf(1, 2, 3, 4, 5)
val randomIndex = Random.nextInt(list.size);
val randomElement = list[randomIndex]
// here we can use the selected element to print it for example
println(randomElement)
}
Since Kotlin 1.3, there’s a built-in method to fetch a random item from a list:
val list = listOf(1, 2, 3, 4, 5)
val randomElement = list.random()
2.2. Random Elements with Sequences
A sequence is a container Sequence
We can take advantage of the operations available for Sequence types to get a random element from a list, using the built-in shuffled() method that is available since Kotlin 1.2:
fun randomElementUsingSequences() {
val list = listOf("one", "two", "three", "four", "five")
val randomElement = list.asSequence().shuffled().find { true }
// use the selected element or print it out
}
2.3. Multiple Random Elements
Sometimes, we need to pick more than one random element from a list. In case we don’t care about getting the same elements in consequent executions, we can keep them inside the list:
fun randomElementsFromGivenList() {
val list = listOf("one", "two", "three", "four", "five")
val numberOfElements = 2
val randomElements = list.asSequence().shuffled().take(numberOfElements).toList()
// use the selected elements or print it out
}
If we’re always expecting different elements for each execution or the requirement is to extract all the items randomly, we need to remove the selected elements from the list.
It’s important to remember that the List type is immutable, so we can’t add or update the original list. Therefore, we’ll need to use MutableList to be able to remove elements:
val list = mutableListOf("one", "two", "three", "four", "five")
val randomElements = list.asSequence().shuffled().take(numberOfElements).toList()
list.removeIf { i -> randomElements.contains(i) }
2.4. Random Elements in Multithread Environments
We need to ensure that we get different values for every process accessing the Random instance for multithreaded applications. Since Kotlin doesn’t have native support to do this, we need to use Java’s ThreadLocalRandom class:
fun randomElementMultithreaded() {
val list = listOf("one", "two", "three", "four", "five")
val randomIndex: Int = ThreadLocalRandom.current().nextInt(list.size)
val randomElement = list[randomIndex]
// use the selected element or print it out
}
3. Conclusion
In this article, we saw some efficient implementations to obtain random elements from a list in Kotlin considering different use cases and scenarios.
As always, the complete code for this article is available over on GitHub.