Ultimate Kotlin Cheatsheet

Table of Contents Basics Variables & Data Types Control Flow Functions Collections Classes & Objects Null Safety Coroutines Extension Functions Functional Programming Learning Resources Basics Hello World fun main() { println("Hello, World!") } Comments // Single-line comment /* Multi-line comment */ /** * KDoc comment * @param args command line arguments */ Variables & Data Types Variable Declaration val immutable: String = "Cannot be changed" // Read-only (immutable) var mutable: String = "Can be changed" // Mutable mutable = "New value" // Type inference val inferred = "Type is inferred as String" Basic Types // Numbers val byte: Byte = 127 // 8 bits val short: Short = 32767 // 16 bits val int: Int = 2147483647 // 32 bits val long: Long = 9223372036854775807L // 64 bits val float: Float = 3.14f // 32 bits val double: Double = 3.14159 // 64 bits // Characters and strings val char: Char = 'A' val string: String = "Hello" val multiline: String = """ This is a multiline string No escaping needed """ // Boolean val boolean: Boolean = true // Type conversion val longFromInt: Long = int.toLong() String Templates val name = "Kotlin" println("Hello, $name!") // Simple variable println("Array size: ${array.size}") // Expression Control Flow Conditionals // If expression (returns a value) val max = if (a > b) a else b // If statement if (x > 0) { println("Positive") } else if (x println("One") 2, 3 -> println("Two or Three") in 4..10 -> println("Between 4 and 10") !in 20..30 -> println("Not between 20 and 30") is String -> println("Is a String of length ${x.length}") else -> println("Otherwise") } // When as an expression val result = when (x) { 0, 1 -> "Binary digit" else -> "Not a binary digit" } Loops // For loop with range for (i in 1..5) { println(i) // 1, 2, 3, 4, 5 } // For loop with step for (i in 1..10 step 2) { println(i) // 1, 3, 5, 7, 9 } // For loop downward for (i in 5 downTo 1) { println(i) // 5, 4, 3, 2, 1 } // For loop with indices for (i in array.indices) { println(array[i]) } // For loop with index for ((index, value) in array.withIndex()) { println("Element at $index is $value") } // While loop while (condition) { // code } // Do-while loop do { // code } while (condition) Loop Control // Break for (i in 1..10) { if (i == 5) break println(i) // 1, 2, 3, 4 } // Continue for (i in 1..10) { if (i % 2 == 0) continue println(i) // 1, 3, 5, 7, 9 } // Labeled break/continue outer@ for (i in 1..10) { for (j in 1..10) { if (i * j > 50) break@outer } } Functions Basic Function fun greet(name: String): String { return "Hello, $name!" } // Single-expression function fun greet(name: String): String = "Hello, $name!" // Type inference for return value fun greet(name: String) = "Hello, $name!" Parameters // Default parameters fun greet(name: String, greeting: String = "Hello") = "$greeting, $name!" // Named arguments greet(greeting = "Hi", name = "Kotlin") // Variable number of arguments (varargs) fun sum(vararg numbers: Int): Int { return numbers.sum() } sum(1, 2, 3, 4) // 10 // Spread operator for varargs val numbers = intArrayOf(1, 2, 3) sum(*numbers) Local Functions fun outer() { fun inner() { // Has access to outer's scope } inner() } Infix Functions infix fun Int.plus(other: Int): Int = this + other val result = 1 plus 2 // Same as 1.plus(2) Operator Overloading operator fun Point.plus(other: Point): Point { return Point(x + other.x, y + other.y) } val result = point1 + point2 // Calls point1.plus(point2) Higher-Order Functions // Function that takes a function as parameter fun operation(x: Int, y: Int, op: (Int, Int) -> Int): Int { return op(x, y) } // Calling with lambda operation(1, 2) { a, b -> a + b } // Function that returns a function fun multiplier(factor: Int): (Int) -> Int { return { it * factor } } val double = multiplier(2) double(5) // 10 Collections Creating Collections // Immutable collections (preferred) val list = listOf(1, 2, 3) // List val set = setOf("apple", "banana") // Set val map = mapOf("a" to 1, "b" to 2) // Map // Mutable collections val mutableList = mutableListOf(1, 2, 3) val mutableSet = mutableSetOf("apple", "banana") val mutableMap = mutableMapOf("a" to 1, "b" to 2) // Empty collections val emptyList = emptyList() val emptySet = emptySet() val emptyMap = emptyMap() // Array val array = arrayOf(1, 2, 3) val intArray = intArrayOf(1, 2, 3) // Pr

Mar 29, 2025 - 17:24
 0
Ultimate Kotlin Cheatsheet

Table of Contents

  • Basics
  • Variables & Data Types
  • Control Flow
  • Functions
  • Collections
  • Classes & Objects
  • Null Safety
  • Coroutines
  • Extension Functions
  • Functional Programming
  • Learning Resources

Basics

Hello World

fun main() {
    println("Hello, World!")
}

Comments

// Single-line comment

/*
   Multi-line
   comment
*/

/**
 * KDoc comment
 * @param args command line arguments
 */

Variables & Data Types

Variable Declaration

val immutable: String = "Cannot be changed" // Read-only (immutable)
var mutable: String = "Can be changed"      // Mutable
mutable = "New value"

// Type inference
val inferred = "Type is inferred as String"

Basic Types

// Numbers
val byte: Byte = 127                // 8 bits
val short: Short = 32767            // 16 bits
val int: Int = 2147483647           // 32 bits
val long: Long = 9223372036854775807L // 64 bits
val float: Float = 3.14f            // 32 bits
val double: Double = 3.14159        // 64 bits

// Characters and strings
val char: Char = 'A'
val string: String = "Hello"
val multiline: String = """
    This is a
    multiline string
    No escaping needed
"""

// Boolean
val boolean: Boolean = true

// Type conversion
val longFromInt: Long = int.toLong()

String Templates

val name = "Kotlin"
println("Hello, $name!")              // Simple variable
println("Array size: ${array.size}")  // Expression

Control Flow

Conditionals

// If expression (returns a value)
val max = if (a > b) a else b

// If statement
if (x > 0) {
    println("Positive")
} else if (x < 0) {
    println("Negative")
} else {
    println("Zero")
}

// When expression (enhanced switch)
when (x) {
    1 -> println("One")
    2, 3 -> println("Two or Three")
    in 4..10 -> println("Between 4 and 10")
    !in 20..30 -> println("Not between 20 and 30")
    is String -> println("Is a String of length ${x.length}")
    else -> println("Otherwise")
}

// When as an expression
val result = when (x) {
    0, 1 -> "Binary digit"
    else -> "Not a binary digit"
}

Loops

// For loop with range
for (i in 1..5) {
    println(i) // 1, 2, 3, 4, 5
}

// For loop with step
for (i in 1..10 step 2) {
    println(i) // 1, 3, 5, 7, 9
}

// For loop downward
for (i in 5 downTo 1) {
    println(i) // 5, 4, 3, 2, 1
}

// For loop with indices
for (i in array.indices) {
    println(array[i])
}

// For loop with index
for ((index, value) in array.withIndex()) {
    println("Element at $index is $value")
}

// While loop
while (condition) {
    // code
}

// Do-while loop
do {
    // code
} while (condition)

Loop Control

// Break
for (i in 1..10) {
    if (i == 5) break
    println(i) // 1, 2, 3, 4
}

// Continue
for (i in 1..10) {
    if (i % 2 == 0) continue
    println(i) // 1, 3, 5, 7, 9
}

// Labeled break/continue
outer@ for (i in 1..10) {
    for (j in 1..10) {
        if (i * j > 50) break@outer
    }
}

Functions

Basic Function

fun greet(name: String): String {
    return "Hello, $name!"
}

// Single-expression function
fun greet(name: String): String = "Hello, $name!"

// Type inference for return value
fun greet(name: String) = "Hello, $name!"

Parameters

// Default parameters
fun greet(name: String, greeting: String = "Hello") = "$greeting, $name!"

// Named arguments
greet(greeting = "Hi", name = "Kotlin")

// Variable number of arguments (varargs)
fun sum(vararg numbers: Int): Int {
    return numbers.sum()
}
sum(1, 2, 3, 4) // 10

// Spread operator for varargs
val numbers = intArrayOf(1, 2, 3)
sum(*numbers)

Local Functions

fun outer() {
    fun inner() {
        // Has access to outer's scope
    }
    inner()
}

Infix Functions

infix fun Int.plus(other: Int): Int = this + other
val result = 1 plus 2 // Same as 1.plus(2)

Operator Overloading

operator fun Point.plus(other: Point): Point {
    return Point(x + other.x, y + other.y)
}
val result = point1 + point2 // Calls point1.plus(point2)

Higher-Order Functions

// Function that takes a function as parameter
fun operation(x: Int, y: Int, op: (Int, Int) -> Int): Int {
    return op(x, y)
}

// Calling with lambda
operation(1, 2) { a, b -> a + b }

// Function that returns a function
fun multiplier(factor: Int): (Int) -> Int {
    return { it * factor }
}
val double = multiplier(2)
double(5) // 10

Collections

Creating Collections

// Immutable collections (preferred)
val list = listOf(1, 2, 3)             // List
val set = setOf("apple", "banana")     // Set
val map = mapOf("a" to 1, "b" to 2)    // Map

// Mutable collections
val mutableList = mutableListOf(1, 2, 3)
val mutableSet = mutableSetOf("apple", "banana")
val mutableMap = mutableMapOf("a" to 1, "b" to 2)

// Empty collections
val emptyList = emptyList<String>()
val emptySet = emptySet<Int>()
val emptyMap = emptyMap<String, Int>()

// Array
val array = arrayOf(1, 2, 3)
val intArray = intArrayOf(1, 2, 3)     // Primitive int[]

Collection Operations

// Element access
list[0]                  // First element
list.first()             // First element
list.last()              // Last element
map["a"]                 // Value for key "a"

// Adding elements (mutable collections)
mutableList.add(4)
mutableSet.add("cherry")
mutableMap["c"] = 3

// Removing elements (mutable collections)
mutableList.remove(2)
mutableSet.remove("apple")
mutableMap.remove("a")

// Collection transformations
val doubled = list.map { it * 2 }            // [2, 4, 6]
val even = list.filter { it % 2 == 0 }       // [2]
val sum = list.reduce { acc, i -> acc + i }  // 6
val grouped = list.groupBy { it % 2 }        // {1=[1, 3], 0=[2]}
val flattened = listOf(listOf(1), listOf(2, 3)).flatten() // [1, 2, 3]

// Checking elements
list.contains(2)         // true
2 in list                // true
list.any { it > 2 }      // true
list.all { it < 10 }     // true
list.none { it < 0 }     // true
list.count { it % 2 == 0 } // 1

// Collection information
list.size                // 3
list.isEmpty()           // false
list.isNotEmpty()        // true

// Finding elements
list.find { it > 2 }     // 3
list.findLast { it < 3 } // 2
list.indexOf(2)          // 1

// Sorting
list.sorted()            // Natural order
list.sortedDescending()  // Reverse natural order
list.sortedBy { it % 2 } // Custom order

Classes & Objects

Class Declaration

class Person {
    var name: String = ""
    var age: Int = 0

    fun introduce() {
        println("I'm $name, $age years old")
    }
}

// Instantiation
val person = Person()
person.name = "John"
person.age = 25
person.introduce()

Constructors

// Primary constructor
class Person(val name: String, var age: Int) {
    // Init blocks run in sequence with property initializers
    init {
        require(age >= 0) { "Age cannot be negative" }
    }
}

// Secondary constructor
class Person {
    val name: String
    var age: Int

    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }

    constructor(name: String) : this(name, 0)
}

Properties

class Person {
    // Backing field auto-generated
    var name: String = ""
        get() = field.uppercase()
        set(value) {
            field = value.trim()
        }

    // Custom getter (read-only property)
    val isAdult: Boolean
        get() = age >= 18

    // Late-initialized property (no initial value needed)
    lateinit var job: String

    // Lazy property - initialized on first access
    val socialSecurityNumber: String by lazy {
        calculateSSN() // Expensive operation
    }
}

Data Classes

// Automatically implements equals(), hashCode(), toString(), copy()
data class User(val name: String, val age: Int)

val user1 = User("John", 25)
val user2 = user1.copy(age = 26)
val (name, age) = user1 // Destructuring declaration

Inheritance

// All classes are final by default
open class Animal(val name: String) {
    open fun makeSound() {
        println("Some sound")
    }
}

class Dog(name: String) : Animal(name) {
    override fun makeSound() {
        println("Woof!")
    }
}

Abstract Classes

abstract class Shape {
    abstract val area: Double
    abstract fun draw()

    // Non-abstract function
    fun display() {
        println("Displaying shape with area: $area")
    }
}

class Circle(val radius: Double) : Shape() {
    override val area: Double
        get() = Math.PI * radius * radius

    override fun draw() {
        println("Drawing a circle")
    }
}

Interfaces

interface Clickable {
    // Abstract property
    val clickCount: Int

    // Abstract method
    fun onClick()

    // Method with default implementation
    fun showOff() {
        println("I'm clickable!")
    }
}

interface Focusable {
    fun showOff() {
        println("I'm focusable!")
    }
}

// Multiple interface implementation
class Button : Clickable, Focusable {
    override val clickCount: Int = 0

    override fun onClick() {
        println("Button clicked")
    }

    // Must override conflicting method
    override fun showOff() {
        super<Clickable>.showOff()
        super<Focusable>.showOff()
    }
}

Singleton (Object)

object Singleton {
    val property = "I'm a singleton"
    fun method() = "Only one instance exists"
}

// Usage
Singleton.property
Singleton.method()

Companion Object

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

// Usage (like static methods in Java)
val instance = MyClass.create()

Enum Classes

enum class Direction {
    NORTH, EAST, SOUTH, WEST
}

// Enum with properties and methods
enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF);

    fun containsRed(): Boolean = (rgb and 0xFF0000 != 0)
}

Sealed Classes

// Restricted class hierarchy
sealed class Result {
    class Success(val data: Any) : Result()
    class Error(val message: String) : Result()
    object Loading : Result()
}

// Ideal for use with when
fun handleResult(result: Result) = when (result) {
    is Result.Success -> println("Success: ${result.data}")
    is Result.Error -> println("Error: ${result.message}")
    is Result.Loading -> println("Loading...")
    // No else branch needed as all subclasses are covered
}

Type Aliases

typealias ClickHandler = (Button, ClickEvent) -> Unit
typealias StringMap = Map<String, String>

Null Safety

Nullable Types

// Non-nullable type
var nonNull: String = "value"
nonNull = null // Compilation error

// Nullable type
var nullable: String? = "value"
nullable = null // OK

Safe Calls

// Returns null if user is null
val length = user?.name?.length

// Chain of safe calls
val city = user?.address?.city

// Safe call with let
user?.let {
    println("User name is ${it.name}")
}

Elvis Operator

// Default value if null
val length = str?.length ?: 0

// Throw exception if null
val name = user?.name ?: throw IllegalArgumentException("User must have a name")

Not-null Assertion

// Throws NullPointerException if null
val length = str!!.length

Safe Casts

// Returns null if cast fails
val str: String? = value as? String

Platform Types

// Types coming from Java are treated as platform types (neither nullable nor non-null)
// import java.util.Date
// fun getDate(): Date = Date() // Java method
// val date: Date = getDate() // Treated as non-nullable
// val nullableDate: Date? = getDate() // Treated as nullable

Coroutines

Basic Coroutine

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000)
        println("World!")
    }
    println("Hello,")
}
// Prints: Hello, (waits 1 second) World!

Coroutine Builders

// launch - fire and forget
launch {
    // Coroutine code
}

// async - returns a result
val deferred = async {
    // Coroutine code that returns a value
    "Result"
}
val result = deferred.await()

// runBlocking - bridges blocking and non-blocking worlds
runBlocking {
    // Coroutine code
}

// coroutineScope - creates a new scope and waits for all children
coroutineScope {
    launch { delay(1000) }
    launch { delay(2000) }
} // Waits for both launches to complete

Coroutine Context & Dispatchers

// Dispatchers
launch(Dispatchers.Default) { /* CPU-intensive work */ }
launch(Dispatchers.IO) { /* I/O operations */ }
launch(Dispatchers.Main) { /* UI updates */ }

// Named coroutines for debugging
launch(CoroutineName("my-coroutine")) { /* ... */ }

// Combined context
launch(Dispatchers.IO + CoroutineName("io-work")) { /* ... */ }

// Job for cancellation control
val job = launch { /* ... */ }
job.cancel()
job.join() // Wait for completion

Exception Handling

val handler = CoroutineExceptionHandler { _, exception ->
    println("Caught $exception")
}

val job = GlobalScope.launch(handler) {
    throw RuntimeException("Oops")
}

// supervisorScope for independent failure of children
supervisorScope {
    val job1 = launch { /* may fail */ }
    val job2 = launch { /* continues even if job1 fails */ }
}

Flow

// Creating a flow
val flow = flow {
    for (i in 1..3) {
        delay(100)
        emit(i)
    }
}

// Collecting a flow
flow.collect { value ->
    println(value)
}

// Flow operators
flow.map { it * 2 }
    .filter { it > 0 }
    .take(2)
    .collect { println(it) }

Extension Functions

Basic Extension Function

// Add a method to String class
fun String.addExclamation(): String {
    return this + "!"
}

// Usage
val excited = "Hello".addExclamation() // "Hello!"

Extension Properties

val String.lastChar: Char
    get() = this[length - 1]

// Usage
val last = "Kotlin".lastChar // 'n'

Nullable Receiver

fun String?.isNullOrBlank(): Boolean {
    return this == null || this.isBlank()
}

// Usage
val result = null.isNullOrBlank() // true

Companion Object Extensions

class MyClass {
    companion object {}
}

fun MyClass.Companion.create(): MyClass = MyClass()

// Usage
val instance = MyClass.create()

Functional Programming

Lambda Expressions

// Full syntax
val sum = { a: Int, b: Int -> a + b }

// Type inference
val multiply: (Int, Int) -> Int = { a, b -> a * b }

// Calling a lambda
sum(1, 2) // 3

// Lambda with receiver
val greet: String.() -> String = { "Hello, $this!" }
"Kotlin".greet() // "Hello, Kotlin!"

Function References

// Reference to a function
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
numbers.filter(::isOdd) // [1, 3]

// Reference to a constructor
class Person(val name: String)
val createPerson = ::Person
val person = createPerson("John")

// Reference to an instance method
val predicate = String::isNotEmpty

Higher-Order Functions

// Standard library examples
val numbers = listOf(1, 2, 3, 4)
numbers.filter { it % 2 == 0 }      // [2, 4]
numbers.map { it * it }             // [1, 4, 9, 16]
numbers.forEach { println(it) }     // Prints each number
numbers.fold(0) { acc, n -> acc + n } // 10

Sequences

// Lazy evaluation (more efficient for chained operations)
val result = sequenceOf(1, 2, 3, 4)
    .filter { println("Filter: $it"); it % 2 == 0 }
    .map { println("Map: $it"); it * it }
    .first() // Only processes elements until first result

// Generate sequences
val fibonacci = sequence {
    var a = 0
    var b = 1
    while (true) {
        yield(a)
        val next = a + b
        a = b
        b = next
    }
}
fibonacci.take(5).toList() // [0, 1, 1, 2, 3]

Scope Functions

// let - object as it, returns lambda result
val length = str?.let {
    println("Processing '$it'")
    it.length
}

// run - object as this, returns lambda result
val upperCase = str.run {
    println("Processing '$this'")
    uppercase()
}

// with - object as this, returns lambda result (extension-like)
val result = with(str) {
    println("Processing '$this'")
    length * 2
}

// apply - object as this, returns the object (builder-like)
val person = Person().apply {
    name = "John"
    age = 30
}

// also - object as it, returns the object (side effects)
val numbers = mutableListOf(1, 2, 3)
    .also { println("List: $it") }
    .also { it.add(4) }

Learning Resources

Official Resources

Books

  • "Kotlin in Action" by Dmitry Jemerov and Svetlana Isakova
  • "Atomic Kotlin" by Bruce Eckel and Svetlana Isakova
  • "Programming Kotlin" by Venkat Subramaniam
  • "Head First Kotlin" by Dawn Griffiths and David Griffiths

Online Courses

Community

Blogs and Websites

Frameworks and Libraries

Practice Platforms