Contrast in-place sort() / sortWith() on MutableList with the sorted() / sortedWith() copying functions. When would you pick each, and what are the return types and receiver constraints?
answer
- '-ed' = copy + return List; no '-ed' = mutate + Unit
- sort*/sortWith only on MutableList & arrays
- sorted*/sortedWith on any Iterable
- In-place saves an allocation
- Copying preserves the original / works on read-only
basics
~20 ssort() and sortWith() rearrange an existing mutable list and return nothing. sorted() and sortedWith() make a new sorted list and leave the original alone. Use in-place to save memory; use copying when the original must stay intact or the list is read-only.
solid answer
~40 sThe in-place functions — sort(), sortDescending(), sortBy { }, sortByDescending { }, sortWith(comparator) — are declared only on MutableList (and arrays). They mutate the receiver and return Unit. The copying functions — sorted(), sortedDescending(), sortedBy { }, sortedByDescending { }, sortedWith(comparator) — are on any Iterable/Array, return a new List<T>, and never touch the receiver. Pick in-place when you own a MutableList, want to avoid an extra allocation, and don't need the original order. Pick copying for read-only Lists, shared/immutable data, or when you need both orders. Both are stable. A common pitfall: calling sort() and expecting a return value (it's Unit), or calling sorted() and forgetting to use the returned list because the original is unchanged.
code
kotlin · 6 linesval original = listOf("b", "a", "c")
val copy = original.sorted() // [a,b,c]; original still [b,a,c]
val m = original.toMutableList()
val result = m.sort() // result: Unit; m now [a,b,c]
// original.sort() // COMPILE ERROR: read-only List has no sort()go deeper
Knows there are two variants and that '-ed' returns a new list.
States the return types (Unit vs List), receiver constraints (MutableList vs Iterable), and picks correctly by use case.
Weighs allocation cost vs preserving the original, mentions stability and primitive-array fast paths.
Decides API surface for a library (offer copying for immutability-by-default, in-place only on owned mutable buffers) and reasons about hot-path allocation pressure.
## Two families, two contracts Kotlin separates ordering into **mutating** and **non-mutating** operations, and the naming encodes it: the `-ed` suffix means "copy and return". ### In-place (mutating) — MutableList / Array only ```kotlin val m = mutableListOf(3, 1, 2) m.sort() // m is now [1, 2, 3], returns Unit m.sortDescending() // m is now [3, 2, 1] m.sortBy { it } // by selector, in place m.sortWith(compareBy { it }) ``` These are **not available on a read-only `List`** — `listOf(...).sort()` does not compile. They return `Unit`, so `val x = m.sort()` gives `x: Unit`. ### Copying (non-mutating) — any Iterable ```kotlin val r = listOf(3, 1, 2) val s = r.sorted() // s = [1,2,3], r unchanged val d = r.sortedDescending() val w = r.sortedWith(compareBy { it }) ``` These return a **new `List<T>`**; the receiver is untouched. They work on read-only lists, sets (returning a List), and arrays. ## Choosing - **In-place** when: you hold a `MutableList`, want to avoid allocating a second list (large data, hot path), and the original order is disposable. - **Copying** when: the source is read-only or shared/immutable, you must preserve the original, you need several differently-sorted views, or you're in a functional pipeline (`xs.sortedBy { }.take(5)`). ## Performance & stability Both families ultimately delegate to a **stable** sort (TimSort-style via `java.util.Arrays.sort` for object arrays). In-place avoids one copy; copying allocates a new backing array. For primitives, sorting an `IntArray` in place is cheapest. ## Pitfalls - Expecting `sort()` to return the sorted list — it returns `Unit`. - Calling `sorted()` and then reading the original, expecting it changed — it didn't. - Trying in-place sort on a list produced by `listOf`/`List(...)` — those are read-only.
- Why doesn't listOf(3,1,2).sort() compile?sort() is an extension on MutableList; a read-only List produced by listOf has no sort(). Use sorted() (copy) or toMutableList().sort().
- What does sort() return?Unit — it mutates the receiver in place. Only the sorted*/sortedWith family returns a new List.
In-place sort is reorganizing the books on your one shelf; copying sort is buying a second shelf, arranging copies, and leaving the first shelf as-is.
saying these in an interview costs you the question
- Assigning the result of sort() expecting the sorted list
- Calling in-place sort on a read-only List and expecting it to compile
- Thinking sorted() mutates to save memory
- Not knowing both families are stable