Kotlin Cheatsheet

Collections

Use this Kotlin reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Creating collections

ExpressionResult
listOf(1, 2, 3)read-only List<Int>
mutableListOf<Int>()MutableList<Int>
setOf("a") / mutableSetOf()(Linked)HashSet-backed
mapOf("a" to 1) / mutableMapOf()(Linked)HashMap-backed
arrayOf(1, 2), intArrayOf(1, 2)arrays (IntArray is unboxed)
List(n) { it * it }sized initializer
Array(n) { 0 }, IntArray(n)array initializers
buildList { add(1); addAll(xs) }builder → read-only list
emptyList(), emptyMap()shared empty instances

Read-only interfaces (List, Set, Map) block mutation through that reference; the underlying object may still change elsewhere. toList() / toMutableList() copy.

Transformations

nums.map { it * it }                       // [1,4,9]
nums.mapIndexed { i, x -> i * x }
nums.filter { it > 0 }; nums.filterNot { it > 0 }
nums.flatMap { listOf(it, -it) }           // map + flatten
nested.flatten()
words.associateWith { it.length }          // {word=len}
words.associateBy { it.first() }           // {firstChar=word} (last wins)
pairs.toMap(); map.toList()
nums.distinct(); people.distinctBy { it.name }
nums.sorted(); nums.sortedDescending()
people.sortedBy { it.age }; people.sortedWith(compareBy({ it.age }, { it.name }))
nums.reversed(); nums.take(3); nums.drop(3); nums.takeWhile { it < 5 }

Aggregation & grouping

nums.sum(); nums.average(); nums.count { it > 0 }
nums.maxOrNull(); people.maxByOrNull { it.age }
orders.sumOf { it.total }                  // works for Int/Long/Double/BigDecimal
nums.fold(1L) { acc, x -> acc * x }        // with initial value
nums.reduce { acc, x -> acc + x }          // no initial; throws on empty
nums.runningFold(0) { acc, x -> acc + x }  // prefix sums (n+1 elements)
words.groupBy { it.length }                // Map<Int, List<String>>
words.groupingBy { it }.eachCount()        // frequency map
val (evens, odds) = nums.partition { it % 2 == 0 }

Slicing, zipping, windows

nums.chunked(3)                            // [[1,2,3],[4,5,6],...]
nums.windowed(3)                           // sliding windows, size 3
nums.windowed(3, step = 1) { it.sum() }    // transform each window
nums.zip(others)                           // List<Pair<A,B>>, shortest wins
nums.zipWithNext { a, b -> b - a }         // deltas
names.zip(ages) { n, a -> Person(n, a) }
val (names2, ages2) = pairs.unzip()
nums.slice(1..3); nums.subList(1, 4)

Sequences (lazy pipelines)

val firstBig = nums.asSequence()
    .map { it * it }          // no intermediate lists
    .filter { it > 1_000 }
    .first()                  // stops at first match

generateSequence(1L) { it * 2 }.takeWhile { it < 1e9 }.toList()
sequence { yield(1); yieldAll(listOf(2, 3)) }

Use sequences for long chains on large inputs or early termination; plain lists are faster for short chains. Terminal ops (toList, first, sum) trigger evaluation.

Deques, stacks, heaps

kotlin.collections.ArrayDeque (stdlib, no import) is the idiomatic queue/stack:

val dq = ArrayDeque<Int>()
dq.addLast(1); dq.addFirst(0)
dq.removeFirst(); dq.removeLast()
dq.first(); dq.last()

// Heaps have no stdlib type — use Java's PriorityQueue:
import java.util.PriorityQueue
val minHeap = PriorityQueue<Int>()
val maxHeap = PriorityQueue<Int>(compareByDescending { it })
minHeap.add(3); minHeap.peek(); minHeap.poll()

Map idioms

val counts = mutableMapOf<String, Int>()
counts["a"] = counts.getOrDefault("a", 0) + 1
counts.merge("a", 1, Int::plus)                 // same, one call
val groups = mutableMapOf<Int, MutableList<String>>()
groups.getOrPut(3) { mutableListOf() }.add("cat")
map.mapValues { (_, v) -> v * 2 }; map.filterKeys { it > 0 }
for ((k, v) in map) println("$k=$v")
map.entries.sortedByDescending { it.value }.take(5)