Kotlin Quick Reference
Everything you need day‑to‑day – modern, concise, and expressive.
Basic Syntax
// Entry point fun main() { println("Hello, World!") } // Main with arguments fun main(args: Array<String>) { println(args.joinToString()) }
Variables
// Read‑only (val) – immutable val name = "Alice" val age: Int = 25 val pi = 3.14159 // Mutable (var) – reassignable var counter = 0 counter = 1 // Late initialization lateinit var description: String // Lazy initialization val expensive: String by lazy { computeExpensiveValue() } // Type inference val x = 42 // Int val y = 3.14 // Double val z = "hello" // String
Data Types
Primitive Types
Int– 42Double– 3.14Float– 3.14fLong– 42LShort– 42Byte– 42Boolean– true, falseChar– 'A'String– "Hello"
Compound Types
Array<T>– arrayOf(1,2,3)List<T>– listOf(1,2,3)MutableList<T>– mutableListOf(1,2,3)Set<T>– setOf(1,2,3)Map<K,V>– mapOf("a" to 1)Pair<A,B>– "a" to 1Triple<A,B,C>– Triple(1, 2, 3)
Type Aliases
typealias UserMap = Map<String, User> typealias ValidationResult = Result<Boolean, Error>
Null Safety
// Nullable types (?) var name: String? = null var age: Int? = 25 // Safe call (?.) val length = name?.length // Elvis operator (?:) val len = name?.length ?: 0 // Not‑null assertion (!!) val len = name!!.length // throws NPE if null // let (execute if not null) name?.let { println("Name is $it") } // Safe cast (as?) val num = obj as? Int // Smart cast if (name != null) { println(name.length) // automatically cast to non‑null }
Control Flow
if / else
if (x > 0) { println("positive") } else if (x == 0) { println("zero") } else { println("negative") } // If as expression val result = if (x > 0) "positive" else "negative"
when (switch)
when (x) { 1 -> println("one") 2 -> println("two") in 3..10 -> println("3-10") is String -> println("is String") else -> println("other") } // When as expression val result = when (x) { 1 -> "one" 2 -> "two" else -> "other" } // When without argument when { x > 0 -> println("positive") x < 0 -> println("negative") else -> println("zero") }
Loops
// for for (i in 1..5) { println(i) } // Down to for (i in 5 downTo 1) { println(i) } // Step for (i in 1..10 step 2) { println(i) } // Until (excludes upper bound) for (i in 0 until 5) { println(i) // 0,1,2,3,4 } // Iterate over collection for (item in list) { println(item) } for ((index, value) in list.withIndex()) { println("$index: $value") } // while var i = 0 while (i < 5) { println(i++) } // do‑while var i = 0 do { println(i++) } while (i < 5)
Functions
Basic Functions
// Standard function fun add(a: Int, b: Int): Int { return a + b } // Single‑expression function fun add(a: Int, b: Int) = a + b // Unit (void) fun printMessage(msg: String): Unit { println(msg) } // Default arguments fun greet(name: String, greeting: String = "Hello") { println("$greeting, $name") } // Named arguments greet(greeting = "Hi", name = "Alice") // Varargs fun sum(vararg numbers: Int): Int { return numbers.sum() }
Lambda & Higher‑Order Functions
// Lambda val square = { x: Int -> x * x } val square: (Int) -> Int = { it * it } // Higher‑order function fun repeat(times: Int, action: (Int) -> Unit) { for (i in 0 until times) { action(i) } } repeat(5) { println("Iteration $it") } // Inline functions inline fun measure(block: () -> Unit) { val start = System.currentTimeMillis() block() println("Took ${System.currentTimeMillis() - start}ms") }
Extension Functions
// Extension on String fun String.isEmail(): Boolean { return this.contains("@") && this.contains(".") } println("alice@example.com".isEmail()) // true // Extension with receiver fun Int.timesThree() = this * 3 println(5.timesThree()) // 15 // Extension property val String.wordCount: Int get() = this.split(" ").size
Classes & OOP
Basic Class
class Person(val name: String, var age: Int) {
// Secondary constructor
constructor(name: String) : this(name, 0)
// Method
fun greet() = "Hello, $name"
// Property with custom getter/setter
var isAdult: Boolean
get() = age >= 18
set(value) { /* custom */ }
}
Data Class
data class User(val id: Int, val name: String, val email: String)
// Auto‑generated: toString(), equals(), hashCode(), copy()
val user1 = User(1, "Alice", "alice@example.com")
val user2 = user1.copy(id = 2)
Inheritance
open class Animal(val name: String) {
open fun speak() = "$name makes a sound"
}
class Dog(name: String, val breed: String) : Animal(name) {
override fun speak() = "$name barks"
}
// Abstract class
abstract class Shape {
abstract fun area(): Double
}
class Circle(val radius: Double) : Shape() {
override fun area() = Math.PI * radius * radius
}
Sealed Classes
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
object Loading : Result()
}
when (result) {
is Result.Success -> println(result.data)
is Result.Error -> println(result.message)
Result.Loading -> println("Loading...")
}
Interfaces
interface Greetable {
fun greet(): String
fun farewell() = "Goodbye" // default implementation
}
class User(val name: String) : Greetable {
override fun greet() = "Hello, $name"
}
Object Declarations (Singleton)
// Singleton object AppConfig { val version = "1.0.0" fun printVersion() = println(version) } // Companion object (static members) class MyClass { companion object { const val TAG = "MyClass" fun create() = MyClass() } }
Collections
List
// Immutable val list = listOf(1, 2, 3, 4, 5) // Mutable val mutable = mutableListOf(1, 2, 3) mutable.add(4) mutable.removeAt(0) // Operations list.size list.isEmpty() list.first() list.last() list.get(0) // or list[0] list.contains(3) list.indexOf(3) list.subList(1, 3) // Transformations list.map { it * 2 } list.filter { it % 2 == 0 } list.reduce { acc, i -> acc + i } list.fold(0) { acc, i -> acc + i } list.any { it > 3 } list.all { it > 0 } list.none { it < 0 } list.find { it == 3 } list.sort() list.reversed()
Set
val set = setOf(1, 2, 3, 3) // {1, 2, 3}
val mutableSet = mutableSetOf(1, 2, 3)
mutableSet.add(4)
set.union(setOf(4, 5))
set.intersect(setOf(2, 3))
set.subtract(setOf(1, 2))
Map
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
val mutable = mutableMapOf("a" to 1)
mutable["b"] = 2
mutable.put("c", 3)
map.keys
map.values
map.entries
map.get("a") // or map["a"]
map.getOrDefault("d", 0)
map.containsKey("a")
map.filter { it.value > 1 }
map.map { it.key to it.value * 2 }
Sequences (Lazy)
val seq = (1..100).asSequence()
.filter { it % 2 == 0 }
.map { it * 2 }
.take(10)
.toList()
// generateSequence
val nums = generateSequence(0) { it + 1 }
val firstFive = nums.take(5).toList() // [0, 1, 2, 3, 4]
Coroutines
// Dependency: implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core") import kotlinx.coroutines.* // Launch coroutine GlobalScope.launch { delay(1000L) println("Coroutine") } // Suspend function suspend fun fetchData(): String { delay(500L) return "Data" } // Run blocking runBlocking { val result = fetchData() println(result) } // With context withContext(Dispatchers.IO) { // heavy I/O } // Parallel val result = coroutineScope { val deferred1 = async { fetchData1() } val deferred2 = async { fetchData2() } deferred1.await() + deferred2.await() } // Timeout withTimeoutOrNull(1000L) { fetchData() } // Flow fun flowExample(): Flow<Int> = flow { for (i in 1..5) { emit(i) delay(100L) } }
Standard Library Functions
Scope Functions
let– it → resultrun– this → resultwith– this → resultapply– this → thisalso– it → it
Examples
obj?.let { println(it) }val result = run { compute() }with(obj) { name = "Alice" }obj.apply { name = "Alice" }obj.also { log(it) }
Common Functions
// String "hello".uppercase() "HELLO".lowercase() " hello ".trim() "a,b,c".split(",") "hello".reversed() "hello".substring(1, 3) // Math listOf(1, 2, 3).sum() listOf(1, 2, 3).average() listOf(1, 2, 3).maxOrNull() listOf(1, 2, 3).minOrNull() (1..10).random() // Pair / Triple val pair = "a" to 1 val (key, value) = pair val triple = Triple(1, 2, 3) val (a, b, c) = triple
Best Practices
- Use
valovervar– prefer immutability. - Use data classes – for simple data holders.
- Use extension functions – to add functionality to existing classes.
- Use nullable types –
?to indicate nullability. - Use scope functions –
let,run,apply,alsofor concise code. - Use
wheninstead of longif/elsechains. - Use coroutines – for asynchronous programming.
- Use sealed classes – for restricted class hierarchies.
- Use companion objects – for static‑like members.
- Use type aliases – for complex types.
- Avoid
!!– prefer safe calls (?.) and Elvis (?:). - Use
@JvmStaticand@JvmField– for Java interop. - Use
@OptIn– for experimental APIs. - Follow Kotlin coding conventions – for consistency.
📌 Quick Reference
Variables:
Null safety:
Functions:
Classes:
Collections:
Scope functions:
Coroutines:
When: Kotlin's
val (read‑only), var (mutable)Null safety:
? (nullable), ?. (safe call), ?: (Elvis)Functions:
fun name(args): ReturnTypeClasses:
class, data class, sealed classCollections:
listOf, mapOf, setOf, mutableScope functions:
let, run, with, apply, alsoCoroutines:
launch, async, delay, suspendWhen: Kotlin's
switch – powerful and expressive