Cheatsheets / Kotlin

Kotlin Cheatsheet

Complete Kotlin reference. Hit Ctrl+P to print.

Variables & Types

val name: String = "Alice"Immutable variable (read-only)
var count: Int = 0Mutable variable
val name = "Alice"Type inference
val x: Int? = nullNullable type - appends ?
val n: Int = x ?: 0Elvis operator - use default if null
x?.lengthSafe call - returns null if x is null
x!!.lengthNon-null assertion - throws if null
val s: String = x ?: "default"Null coalescing with Elvis
Int, Long, Double, Float, Boolean, Char, String, Byte, ShortBuilt-in types
val hex = 0xFF; val bin = 0b1010Hex and binary literals
val big = 1_000_000Underscores in numeric literals
val name: String get() = firstName + " " + lastNameCustom getter

Strings

"Hello, $name!"String template - interpolate variable
"Result: ${a + b}"String template - interpolate expression
"""multi\nline"""Raw (multi-line) string
""" hello """.trimIndent()Trim leading whitespace from raw string
"hello".uppercase()Convert to uppercase
"hello".substring(1, 3)Substring (end exclusive)
"a,b,c".split(",")Split to list
"hi".repeat(3)Repeat string
"hello".contains("ell")Check if contains substring
"abc"[0]Access char at index
"hello".toInt()Parse string to Int (throws if invalid)
"hello".toIntOrNull()Parse string to Int or null

Control Flow

if (x > 0) { ... } else { ... }if / else
val label = if (x > 0) "pos" else "neg"if as expression
when (x) { 1 -> "one" 2 -> "two" else -> "other" }when expression - replaces switch
when { x > 0 -> "pos" x < 0 -> "neg" else -> "zero" }when without argument - condition per branch
when (x) { is String -> x.length else -> 0 }when with type check and smart cast
when (x) { in 1..10 -> "small" }when with range check
for (i in 1..10) { }for loop with closed range
for (i in 1 until 10) { }for loop with open-end range (excludes 10)
for (i in 10 downTo 1 step 2) { }Descending range with step
for (item in list) { }Iterate over collection
for ((i, v) in list.withIndex()) { }Iterate with index
while (x > 0) { }while loop
do { } while (x > 0)do-while loop
break / continueExit loop / skip iteration
break@outerBreak outer loop with label

Functions

fun greet(name: String): String { return "Hi $name" }Function declaration
fun greet(name: String) = "Hi $name"Single-expression function
fun greet(name: String = "World"): StringDefault parameter
fun greet(name: String, greeting: String = "Hi")Multiple default parameters
greet(greeting = "Hello", name = "Alice")Named arguments - any order
fun sum(vararg nums: Int): IntVararg parameter
sum(*intArray)Spread operator for vararg
val double = { x: Int -> x * 2 }Lambda expression
val double: (Int) -> Int = { it * 2 }Lambda with it - single-param shorthand
list.filter { it > 0 }Lambda as trailing argument
fun <T> identity(x: T): T = xGeneric function
tailrec fun fact(n: Int, acc: Int = 1): IntTail-recursive function
inline fun <reified T> check(x: Any) = x is TInline function with reified type
infix fun Int.times(str: String) = str.repeat(this)Infix function

Classes

class User(val name: String, var age: Int)Primary constructor with properties
class User(name: String) { val upper = name.uppercase() }Property initializer in body
init { /* runs in constructor */ }Init block - part of primary constructor
constructor(name: String, id: Int) : this(name)Secondary constructor
class Admin : User(name)Inherit from class - call parent constructor
open class Base / final class SubClasses are final by default; open to allow inheritance
override fun toString(): StringOverride parent method
data class Point(val x: Int, val y: Int)Data class - auto equals, hashCode, copy, toString
val p2 = p1.copy(x = 5)Copy data class with modified field
val (x, y) = pointDestructure data class
sealed class ResultSealed class - all subclasses in same file
object Singleton { fun greet() = "Hi" }Object declaration - singleton
companion object { val TAG = "User" }Companion object - static-like members
class Box<T>(val value: T)Generic class
enum class Direction { NORTH, SOUTH, EAST, WEST }Enum class
enum class Planet(val mass: Double) { EARTH(5.97e24) }Enum with properties

Collections

listOf(1, 2, 3)Immutable list
mutableListOf(1, 2, 3)Mutable list
setOf("a", "b")Immutable set
mutableSetOf("a", "b")Mutable set
mapOf("a" to 1, "b" to 2)Immutable map
mutableMapOf("a" to 1)Mutable map
list.filter { it > 2 }Filter - keep matching elements
list.map { it * 2 }Map - transform each element
list.flatMap { listOf(it, it) }FlatMap - map then flatten
list.fold(0) { acc, x -> acc + x }Fold - reduce with initial value
list.reduce { acc, x -> acc + x }Reduce - fold without initial value
list.groupBy { it.type }Group into map by key selector
list.sortedBy { it.name }Sort by property
list.sortedByDescending { it.age }Sort descending
list.any { it > 5 }True if any element matches
list.all { it > 0 }True if all elements match
list.none { it < 0 }True if no elements match
list.count { it > 0 }Count matching elements
list.first { it > 2 }First matching element (throws if none)
list.firstOrNull { it > 2 }First matching or null
list.take(3) / list.drop(3)Take first N / drop first N elements
list.zip(other)Pair elements from two lists
list.chunked(3)Split into sub-lists of size N

Coroutines

suspend fun fetchData(): StringSuspend function - can be paused
runBlocking { }Run coroutine blocking current thread (testing/main)
CoroutineScope(Dispatchers.IO).launch { }Launch fire-and-forget coroutine
val result = async { fetchData() }async - returns Deferred
val data = result.await()Await deferred result
Dispatchers.MainMain/UI thread dispatcher
Dispatchers.IOIO-optimized dispatcher - network, disk
Dispatchers.DefaultCPU-intensive work dispatcher
withContext(Dispatchers.IO) { }Switch dispatcher within coroutine
delay(1000)Non-blocking delay (milliseconds)
coroutineScope { launch { } launch { } }Structured concurrency - wait for all children
supervisorScope { }Child failures do not cancel siblings
val flow = flow { emit(1); emit(2) }Cold flow - produces values lazily
flow.collect { println(it) }Collect flow values
flow.map { }.filter { }.take(5)Flow operators

Extension Functions & Scope Functions

fun String.shout() = uppercase() + "!"Extension function
"hello".shout()Call extension function
val Int.doubled get() = this * 2Extension property
user.let { println(it.name) }let - transform or use nullable safely
user?.let { /* only if non-null */ }let with safe call - null check pattern
user.also { log(it) }also - side effect, returns receiver
user.apply { name = "Alice"; age = 30 }apply - configure object, returns receiver
user.run { "${name} is ${age}" }run - transform receiver, returns result
with(user) { println(name) }with - non-extension run