How do you create a collection in Kotlin using factory functions like listOf, setOf, and mapOf, and what do they return?
answer
- listOf / setOf / mapOf = read-only
- vararg, no 'new' needed
- map entries use 'to' infix -> Pair
- setOf drops duplicates, keeps first
- order preserved (LinkedHashSet/Map)
basics
~10 sUse listOf(1, 2, 3), setOf(...), or mapOf("a" to 1) to build collections quickly. They give you read-only collections you cannot add to or remove from.
solid answer
~40 sKotlin's standard library provides top-level factory functions instead of constructors. listOf(vararg elements) returns a read-only List, setOf(...) returns a read-only Set, and mapOf(vararg pairs) returns a read-only Map. They use vararg, so listOf(1, 2, 3) just works. The returned types are the read-only List/Set/Map interfaces, which expose no add/remove/put methods, so the collection's structure cannot be changed through that reference. For maps, entries are written with the to infix function: mapOf("a" to 1, "b" to 2). Element order is preserved (listOf keeps insertion order; setOf and mapOf are backed by LinkedHashSet/LinkedHashMap). These factories are the idiomatic, concise way to create collection literals in Kotlin.
code
kotlin · 5 linesval list = listOf(1, 2, 2, 3) // [1, 2, 2, 3]
val set = setOf(1, 2, 2, 3) // [1, 2, 3]
val map = mapOf("a" to 1, "b" to 2) // {a=1, b=2}
println(list[0]) // 1 (index access)
// list.add(4) // does NOT compile: List has no addgo deeper
Can call listOf/setOf/mapOf and knows map entries use 'to'.
Explains read-only return types and that no add/remove is exposed; knows setOf dedups.
Distinguishes read-only from immutable, knows the LinkedHash backing and order guarantees, and the vararg/Pair mechanics.
Frames factory functions as an API-design choice (return the narrowest interface, hide concrete type) and discusses implications for library boundaries.
## What factory functions are Kotlin does not have collection literals like `[1, 2, 3]`. Instead, the standard library (`kotlin.collections`) exposes **top-level factory functions** that you call directly without `new`. They are the idiomatic way to construct collections. ## The read-only trio - `listOf(vararg elements: T): List<T>` — an ordered, indexable collection that may contain duplicates. - `setOf(vararg elements: T): Set<T>` — a collection of unique elements (duplicates dropped, keeping the first occurrence). - `mapOf(vararg pairs: Pair<K, V>): Map<K, V>` — key→value associations with unique keys. All three are declared with **`vararg`**, so you pass elements directly: `listOf(1, 2, 3)`. ```kotlin val nums = listOf(1, 2, 3) // List<Int> val names = setOf("a", "a", "b") // Set<String> = [a, b] val ages = mapOf("Ann" to 30, "Bo" to 25) // Map<String, Int> ``` ## The `to` infix for map entries `mapOf` takes `Pair` values. The **`to`** infix function (`infix fun <A, B> A.to(that: B): Pair<A, B>`) builds a pair, so `"a" to 1` is exactly `Pair("a", 1)`. This is what makes map literals read naturally. ## Read-only, not immutable The declared return types are the **read-only interfaces** `List`, `Set`, `Map`. These interfaces expose no `add`, `remove`, or `put`, so you cannot mutate the structure through that reference. (Read-only is distinct from deep immutability — that is a separate topic.) ## Order guarantees - `listOf` preserves insertion order and allows index access via `get`/`[]`. - `setOf` and `mapOf` preserve insertion order because they are backed by `LinkedHashSet` and `LinkedHashMap`. ## Type inference The element type is inferred from arguments. `listOf(1, 2)` is `List<Int>`; `listOf(1, "x")` becomes `List<Any>` (common supertype). You can also specify it: `listOf<Number>(1, 2L)`.
- Why does listOf return List rather than ArrayList?So the caller gets a read-only view with no add/remove on its surface; the concrete backing type (e.g. an Arrays.ArrayList or singleton) is an implementation detail you should not rely on.
- What does the 'to' in mapOf actually produce?A Pair instance. 'a' to 1 equals Pair("a", 1); mapOf accepts vararg Pair and builds the map from them.
Factory functions are like vending machines: you press a button (call the function) and get a finished, sealed product rather than assembling parts yourself.
saying these in an interview costs you the question
- Claiming listOf returns a mutable list you can add to
- Thinking Kotlin has [1, 2, 3] array/list literals
- Saying setOf keeps duplicates
- Writing mapOf("a", 1) without the 'to' infix
- Believing read-only means the elements themselves are immutable