Kotlin Lambdas
A lambda is a function without a name. You write it inline, right where you need it, instead of defining a separate named function. Lambdas are used heavily with collection operations, callbacks, and higher-order functions.
Lambda Syntax
Normal function:
fun double(x: Int): Int { return x * 2 }
Lambda:
val double = { x: Int -> x * 2 }
↑ ↑
curly braces arrow separates
wrap the lambda params from body
Calling a Lambda
val double = { x: Int -> x * 2 }
println(double(5)) // 10
println(double(11)) // 22Lambda Type
Every lambda has a type that describes what it accepts and what it returns:
(Int) -> Int accepts one Int, returns an Int
(String) -> Boolean accepts a String, returns a Boolean
() -> Unit accepts nothing, returns nothing
(Int, Int) -> Double accepts two Ints, returns a Double
val greet: (String) -> Unit = { name -> println("Hello, $name!") }
val add: (Int, Int) -> Int = { a, b -> a + b }
greet("Meera") // Hello, Meera!
println(add(3,4)) // 7The it Keyword
When a lambda has exactly one parameter, you can skip declaring it and use it as the default name:
val square: (Int) -> Int = { it * it }
println(square(6)) // 36
println(square(9)) // 81Multi-Line Lambda
val processOrder = { item: String, qty: Int ->
val label = item.uppercase()
val message = "$qty × $label ordered"
println(message)
message // last expression is the return value
}
val result = processOrder("pen", 5)
// Prints: 5 × PEN orderedLambdas with Collections
This is where lambdas become very powerful. Collection functions like filter, map, and forEach accept lambdas:
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// filter: keep only items where the lambda returns true
val evens = numbers.filter { it % 2 == 0 }
println(evens) // [2, 4, 6, 8, 10]
// map: transform each item using the lambda
val doubled = numbers.map { it * 2 }
println(doubled) // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
// forEach: run the lambda on each item (no return value)
evens.forEach { println("Even: $it") }Trailing Lambda Syntax
When the last parameter of a function is a lambda, Kotlin allows moving it outside the parentheses. This makes the code look like a built-in language construct:
// Normal call
numbers.filter({ it > 5 })
// Trailing lambda (preferred style)
numbers.filter { it > 5 }
// If there are other arguments:
numbers.fold(0, { acc, item -> acc + item })
// Same as:
numbers.fold(0) { acc, item -> acc + item }Capturing Variables (Closure)
A lambda can access variables from the surrounding scope. This is called a closure:
fun main() {
val threshold = 50
val scores = listOf(45, 78, 30, 92, 55)
val passing = scores.filter { it >= threshold } // threshold captured
println("Passing: $passing") // [78, 92, 55]
}Practical Example: Shopping Filter
data class Product(val name: String, val price: Double, val inStock: Boolean)
fun main() {
val products = listOf(
Product("Headphones", 1500.0, true),
Product("Mouse", 450.0, false),
Product("Keyboard", 800.0, true),
Product("Monitor", 12000.0,true),
Product("USB Hub", 350.0, false)
)
val affordable = products
.filter { it.inStock && it.price < 2000 }
.map { "${it.name} → ₹${it.price}" }
println("Available under ₹2000:")
affordable.forEach { println(" $it") }
}Output:
Available under ₹2000:
Headphones → ₹1500.0
Keyboard → ₹800.0