When working with collections or streams of data in Kotlin, you may come across two frequently used higher-order functions: map
and flatMap
. Although they seem similar, they serve distinct purposes.
In this blog, we will explore the differences between these two functions, their use cases, and how to apply them in real-world scenarios.
map
?The map
function is used to transform each element in a collection into a new value by applying a given function. It returns a new collection where each element is the result of the transformation.
inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R>
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
val squaredNumbers = numbers.map { it * it }
println(squaredNumbers) // Output: [1, 4, 9, 16, 25]
}
Here, the map
function transforms each number in the list into its square.
flatMap
?The flatMap
function is a combination of map
and flatten
. It applies a transformation function to each element of a collection and then flattens the resulting collections into a single collection.
inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R>
fun main() {
val numbers = listOf(1, 2, 3)
val multipliedLists = numbers.flatMap { num -> listOf(num, num * 2, num * 3) }
println(multipliedLists) // Output: [1, 2, 3, 2, 4, 6, 3, 6, 9]
}
In this example, flatMap
transforms each number into a list of its multiples and then flattens those lists into a single list.
map
and flatMap
map
Transformation - Transforms elements individually
Output Structure - Nested structure allowed
Use Case - Simple transformations
flatMap
Transformation - Transforms elements and flattens the result
Output Structure - Always a single flattened structure
Use Case - Handling collections of collections
Suppose you are working with an API response that contains a list of users, and each user has a list of hobbies. You want to extract all hobbies into a single list.
Using flatMap
:
data class User(val name: String, val hobbies: List<String>)
fun main() {
val users = listOf(
User("Alice", listOf("Reading", "Hiking")),
User("Bob", listOf("Gaming", "Cooking")),
User("Charlie", listOf("Swimming", "Cycling"))
)
val allHobbies = users.flatMap { it.hobbies }
println(allHobbies) // Output: [Reading, Hiking, Gaming, Cooking, Swimming, Cycling]
}
Here, flatMap
flattens the nested structure of hobbies into a single list.
Imagine you have a list of orders, and each order contains multiple items. You need a list of all items across all orders.
Using flatMap
:
data class Order(val id: Int, val items: List<String>)
fun main() {
val orders = listOf(
Order(1, listOf("Laptop", "Mouse")),
Order(2, listOf("Phone", "Charger")),
Order(3, listOf("Desk", "Chair"))
)
val allItems = orders.flatMap { it.items }
println(allItems) // Output: [Laptop, Mouse, Phone, Charger, Desk, Chair]
}
Suppose you have a list of product categories, and each category contains a list of products with prices. You want to apply a 10% discount to all products and get a flat list of discounted prices.
Using flatMap
:
data class Product(val name: String, val price: Double)
data class Category(val name: String, val products: List<Product>)
fun main() {
val categories = listOf(
Category("Electronics", listOf(Product("TV", 500.0), Product("Radio", 100.0))),
Category("Furniture", listOf(Product("Sofa", 300.0), Product("Table", 150.0)))
)
val discountedPrices = categories.flatMap { category ->
category.products.map { it.price * 0.9 } // Apply 10% discount
}
println(discountedPrices) // Output: [450.0, 90.0, 270.0, 135.0]
}
map
and flatMap
Use map
when you need to transform individual elements without flattening.
Use flatMap
when you need to transform elements and flatten nested structures.
Understanding the difference between map
and flatMap
is crucial for writing concise and efficient Kotlin code. While map
is ideal for straightforward transformations, flatMap
shines when working with collections of collections. By mastering these functions, you can handle complex data transformations with ease.
Start experimenting with map
and flatMap
in your Kotlin projects today to unlock their full potential!
Akshay Nandwana
Founder AndroidEngineers
You can connect with me on:
Join our upcoming classes
https://www.androidengineers.in/courses