Lambda Expressions
Lambda expression or simply lambda is an anonymous function; a function without name. These functions are passed immediately as an expression without declaration. For example,
fun main(args: Array<String>) {
val greeting = { println("Hello!")}
// invoking function
greeting()
}
When you run the program, the output will be:
Hello!
Here, a lambda expression is assigned to variable greeting. The expression doesn't accept any parameters and doesn't return any value in this program.
Then, the function (lambda expression) is invoked as:
greeting()
Example: Lambda With Parameters and Return Type
The program below has a lambda expression that accepts two integers as parameters, and returns the product of those two integers.
fun main(args: Array<String>) {
val product = { a: Int, b: Int -> a * b }
val result = product(9, 3)
println(result)
}
When you run the program, the output will be:
27
Here, the lambda expression is:
Note, a lambda expression is enclosed inside curly braces.
Higher-Order Function
Koltin has a great support for functional programming. You can pass functions as arguments to other functions. Also, you can return a function from other functions. These functions are called higher-order functions.
Often, lambda expressions are passed to higher-order function (rather than a typical function) for convenience.
Example: Passing Lambda to Function
Let's pass a lambda expression to a higher-order function. Here's how you can do it.
fun callMe(greeting: () -> Unit) {
greeting()
}
fun main(args: Array<String>) {
callMe({ println("Hello!") })
}
When you run the program, the output will be:
Hello!
Here, callMe()
is a higher-order function (because it takes function as a parameter). The greeting parameter accepts the lambda passed to the callMe()
function as:
greeting: () -> Unit
The empty parenthesis suggest that, the passed anonymous function doesn't accept any parameters. And, the Unit
keyword suggest that the anonymous function doesn't return any value.
Lambdas are frequently used while working with collections. And, there are several built-in functions available in standard-library that take lambdas to make our task way easier. You will see couple of examples here:
Example: maxBy() Function
The maxBy() function returns the first element yielding the largest value of the given function or null
if there are no elements.
data class Person(val name: String, val age: Int)
fun main(args: Array<String>) {
val people = listOf(
Person("Jack", 34),
Person("Shelly", 19),
Person("Patrick", 13),
Person("Jill", 12),
Person("Shane", 22),
Person("Joe", 18)
)
val selectedPerson = people.maxBy({ person -> person.age })
println(selectedPerson)
println("name: ${selectedPerson?.name}" )
println("age: ${selectedPerson?.age}" )
}
When you run the program, the output will be:
Person(name=Jack, age=34) name: Jack age: 34
Here, maxBy()
function takes a list of Person objects and returns the Person object having maximum age.
it Keyword: Used for Single Parameter
In the above program, the lambda expression accepts only one parameter (a list of Person objects). In such cases, you can refer the argument by using keyword it
.
You can replace
val selectedPerson = people.maxBy({ person -> person.age })
with
val selectedPerson = people.maxBy({ it.age })
in the above program.
Example: maxBy() and startsWith() Function
The program below computes the maximum age of a Person object starting with letter S.
We will use two library functions maxBy()
and startsWith()
to accomplish this task. The starsWith() function returns true
if it starts with the specified character passed as an argument.
data class Person(val name: String, val age: Int)
fun main(args: Array<String>) {
val people = listOf(
Person("Jack", 34),
Person("Shelly", 19),
Person("Patrick", 13),
Person("Jill", 12),
Person("Shane", 22),
Person("Joe", 18)
)
val selectedPerson = people
.filter { it.name.startsWith("S") }
.maxBy{ it.age }
println(selectedPerson)
println("name: ${selectedPerson?.name}" )
println("age: ${selectedPerson?.age}" )
}
When you run the program, the output will be:
Person(name=Shane, age=22) name: Shane age: 22
Recommended Readings
- Kotlin Closures
- Kotlin With and apply