Explanation of Functional Operations in Kotlin

Posted on 2026-01-06 by Burak Hamdi TUFAN
General Programming
Explanation of Functional Operations in Kotlin
Hello everyone, In this article, we are going to discover the most common functional operations in Kotlin. These are basically map, filter, reduce, flatMap and others with the help of examples.

Let's get started!

In many programming languages, when we are dealing with collections to process or transform the data, it might be difficult to handle the operations. Kotlins set of functional features are making the code clean and understandable.

Let’s start with some basics.

Mapping and Transformation: map

The map function transforms each element of a collection into a new form through a given lambda expression and return the altered collection as a new collection with keeping the old one.


val numbers = listOf(1, 2, 3, 4, 5)
val squares = numbers.map { it * it }

println(squares) // Output: [1, 4, 9, 16, 25]
Here:
  • map applies the transformation { it * it } to every element.
  • The result is a new list; the original remains unchanged.
  • Kotlin’s immutability encourages this style of transformation without side effects.

Filtering Data: filter

To keep only elements that obeys to a condition, we should use filter operation

Here is an example

val numbers = listOf(1, 2, 3, 4, 5)
val even = numbers.filter { it % 2 == 0 }

println(even) // Output: [2, 4]
We can also remove elements with filterNot:

val numbers = listOf(1, 2, 3, 4, 5)
val odd = numbers.filterNot { it % 2 == 0 }
println(odd)  // Output: [1, 3, 5]

We can chain Functional Operations in Kotlin

We can also chain multiple functional operations to express complex transformations concisely.

val result = (1..10)
    .filter { it % 2 == 0 }      // keep even numbers
    .map { it * it }             // square them
    .reduce { acc, value -> acc + value } // sum all squares

println(result)

Each step produces a new list (or value) until the final reduction gives a single result. The usage is clean and readable for handling the complex logic step by step.

Flattening Nested Collections with flatMap

Sometimes you have nested lists like this: List< List< T > > and you may want a single flat list of all of these lists. In this case you can use flatMap.

val people = listOf(
    listOf("Alice", "Bob"),
    listOf("Charlie", "Diana")
)

val flattened = people.flatMap { it }
println(flattened) // Output: [Alice, Bob, Charlie, Diana]

Aggregation with reduce and fold

Both reduce and fold combine elements into a single value. The difference is that fold allows an initial accumulator value and reduce uses the first element as the initial value.


val numbers = listOf(1, 2, 3, 4, 5)

val sum = numbers.reduce { acc, number -> acc + number }
println(sum) // Output: 15

val multply = numbers.fold(1) { acc, number -> acc * number }
println(multply) // Output: 120
  • Use reduce when you don’t need an initial value.
  • Use fold when you want to initialize the accumulator (for example, when summing into a Double or combining with a starting state).

Use Sequence when Lazy Evaluation needed

For large datasets, using regular collection operations may create many intermediate lists. Kotlin’s Sequence API perform the evaluation lazily. It means it processes items one-by-one instead of all at once.

val result = generateSequence(1) { it + 1 }
    .take(1000)
    .filter { it % 2 == 0 }
    .map { it * it }
    .sum()

println(result)

Normally, the regular operations creates intermediate lists for each of functional operation to perform the next process. But here we use Sequence to make it lazy without creating the intermediate collections. This is memory efficient. This is especially useful when chaining many operations on large inputs.

Functional Operations with Custom Types

You can combine functional operations with Kotlin data classes to manipulate complex data easily.

data class User(val name: String, val age: Int)

val users = listOf(
    User("Alice", 28),
    User("Bob", 35),
    User("Charlie", 22),
)

val adults = users.filter { it.age >= 30 }.map { it.name }

println(adults) // Output: [Bob]
Above, we destructed and filtered the collection of data in a readable and declarative way.

A quick list of what we learned in this article:

  • map transform elements
  • filter select subsets
  • flatMap flatten nested structures
  • reduce and fold aggregate results
  • Sequence enable lazy evaluation

That is all.

Burak Hamdi TUFAN


Tags
Share this Post
Send with Whatsapp