What do the random() and shuffled() collection extensions do in Kotlin, and how can you control which generator they use?
answer
- random() one element, shuffled() new ordered list
- shuffle() (no d) mutates in place
- all have a Random overload for seeding
- random() throws on empty, randomOrNull() returns null
- Fisher–Yates under the hood
basics
~10 slist.random() returns one random element; list.shuffled() returns a new list with the elements in random order. Both have overloads taking a Random instance so you can pass a seeded generator.
solid answer
~40 s`Collection.random()` returns a single uniformly-chosen element; on an empty collection it throws `NoSuchElementException`. The null-safe variant `randomOrNull()` returns `null` instead. `Iterable.shuffled()` returns a brand-new `List` with elements in random order, leaving the source untouched (it is non-mutating). For a `MutableList` there is the in-place `shuffle()` (no 'd') that reorders the receiver and returns `Unit`. Each of these has an overload accepting a `Random` argument — `list.random(rng)`, `list.shuffled(rng)`, `mutableList.shuffle(rng)` — so passing a seeded `Random(seed)` makes the selection/order deterministic, which is the standard pattern for testing. `(1..100).random()` works too because ranges support the same extension. Internally shuffled uses a Fisher–Yates shuffle for uniform permutations.
code
kotlin · 5 linesimport kotlin.random.Random
val cards = (1..52).toList()
val dealt = cards.shuffled(Random(7)).take(5) // reproducible 5-card hand
val winner = listOf("a", "b", "c").randomOrNull() // null-safe pickgo deeper
Knows list.random() picks an element and list.shuffled() randomizes order.
Distinguishes shuffled (copy) from shuffle (in place), uses randomOrNull, and seeds via the Random overload.
Knows the Fisher–Yates uniformity guarantee and the empty-collection exception, and injects generators for testability.
Standardizes generator injection across randomized code paths so behavior is testable and reproducible by policy.
## Random-selection extensions Kotlin's stdlib adds randomness helpers directly onto collections so you rarely touch indices by hand. ### Picking one element - `fun <T> Collection<T>.random(): T` — uniformly random element. **Throws `NoSuchElementException` on an empty collection.** - `fun <T> Collection<T>.randomOrNull(): T?` — returns `null` on empty instead of throwing. Prefer this when emptiness is possible. - Overloads `random(random: Random)` / `randomOrNull(random: Random)` accept an explicit generator. ```kotlin val colors = listOf("red", "green", "blue") val pick = colors.random() // uses Random.Default val seededPick = colors.random(Random(1)) // deterministic val safe = emptyList<String>().randomOrNull() // null, no throw ``` ### Reordering - `fun <T> Iterable<T>.shuffled(): List<T>` — returns a **new** list, leaving the original unchanged (non-mutating, returns a value). - `fun <T> MutableList<T>.shuffle()` — reorders the receiver **in place**, returns `Unit`. Note the missing 'd': `shuffle` mutates, `shuffled` returns a copy. - Both take an optional `Random` overload: `shuffled(rng)`, `shuffle(rng)`. ```kotlin val deck = (1..52).toList() val order = deck.shuffled() // new list, deck untouched val m = deck.toMutableList() m.shuffle(Random(42)) // m reordered in place, reproducible ``` ### Algorithm and uniformity `shuffled`/`shuffle` use the **Fisher–Yates** algorithm, which produces every permutation with equal probability when the generator is uniform. `random()` picks an index via `nextInt(size)`. ### Choosing the generator Every one of these defaults to `Random.Default` (unseeded). Passing a `Random` argument is how you inject reproducibility — the same seeded instance gives the same pick or the same shuffle every run, which is the idiomatic way to make tests over randomized logic deterministic. ### Gotchas - `shuffled` (value-returning) vs `shuffle` (in-place) is a common naming trap mirroring `sorted`/`sort` and `reversed`/`reverse`. - `random()` on a possibly-empty collection is a latent crash — reach for `randomOrNull()`.
- What is the difference between shuffle() and shuffled()?shuffle() mutates a MutableList in place and returns Unit; shuffled() returns a new List and leaves the original untouched.
- How do you make a list.random() call deterministic in a test?Pass a seeded generator: list.random(Random(seed)). The same seed picks the same element every run.
shuffled() is photocopying a deck and shuffling the copy; shuffle() is shuffling the deck you're holding.
saying these in an interview costs you the question
- Saying shuffled() mutates the original list
- Using random() on a collection that can be empty without handling NoSuchElementException
- Claiming there is no way to seed these extensions
- Confusing shuffle()'s return value (Unit) with a returned list