Design Converter
Education
Software Development Executive - III
Last updated on Sep 3, 2024
Last updated on Sep 3, 2024
When working with collections in Kotlin, you often need to group elements based on certain criteria. Kotlin provides two powerful functions in its standard library for grouping: groupBy and groupingBy. Though they may seem similar, these functions serve different purposes and have unique use cases.
In this blog, we will explore the differences between groupBy and groupingBy in Kotlin, their syntax, use cases, and how to implement custom operations on grouped data. By the end of this guide, you'll understand how to use these functions effectively in your Kotlin code.
Grouping is a common operation when dealing with collections. It involves categorizing elements based on a key, which is typically derived using a lambda function. The key could be the first character of a string, the result of a mathematical operation, or any other logic defined by a lambda argument. Both groupBy and groupingBy allow you to group collection elements by a key but differ in how they perform operations on the grouped data.
The groupBy function is an extension function provided by the Kotlin standard library that allows you to group all the elements of a collection into a Map<K, List<V>>
. Here, K represents the key and List<V>
contains the values corresponding to that key. This function is quite powerful and can be used to group elements based on any criteria.
1fun <T, K> Iterable<T>.groupBy( 2 keySelector: (T) -> K 3): Map<K, List<T>>
• keySelector is a lambda argument that defines how to determine the key for grouping collection elements.
Let's take a simple example where you group a list of strings by their first letter:
1val names = listOf("Alice", "Bob", "Charlie", "David", "Amanda") 2val groupedByFirstLetter = names.groupBy { it.first() } 3 4println(groupedByFirstLetter)
Output:
1{A=[Alice, Amanda], B=[Bob], C=[Charlie], D=[David]}
In this example, the groupBy function groups the elements of the names list by their first letter.
The groupingBy method returns a Grouping object, which is a specialized interface in Kotlin that allows you to perform aggregate operations on the groups. Unlike groupBy, groupingBy does not immediately return a result map. Instead, it provides an intermediate step where you can perform custom operations on each group.
1fun <T, K> Iterable<T>.groupingBy( 2 keySelector: (T) -> K 3): Grouping<T, K>
• keySelector is a lambda argument used to select the key for grouping elements.
Consider the following example where we group names by their first letter and count the number of names in each group:
1val names = listOf("Alice", "Bob", "Charlie", "David", "Amanda") 2val grouping = names.groupingBy { it.first() }.eachCount() 3 4println(grouping)
Output:
1{A=2, B=1, C=1, D=1}
In this example, the groupingBy method creates a Grouping object, and the eachCount function is applied to count the number of elements in each group.
While both groupBy and groupingBy functions are used for grouping in Kotlin, there are key differences in their usage, performance, and flexibility:
• groupBy: Returns a Map<K, List<V>>
immediately, where you can access the grouped elements directly. It is suitable when you only need to group elements and retrieve the result map.
• groupingBy: Returns a Grouping object, which is more versatile and allows you to implement custom operations like counting, reducing, or aggregating on the groups. You need to call an additional function such as eachCount, fold, or aggregate to get the final result.
• groupBy: Since it immediately creates a Map with grouped data, it might consume more memory for large collections. It is better suited for one-time operations.
• groupingBy: Lazily evaluates the grouping and only computes the result when a terminal operation like eachCount or fold is called. This approach is more memory efficient when performing multiple operations on the same data.
• groupBy: Use this when you need a simple grouping of elements and the resulting map will be used as-is. It is great for straightforward tasks like grouping by the first character or category.
• groupingBy: Ideal when you need to perform multiple or complex operations on grouped data. It allows you to chain methods like fold and aggregate to perform complex data transformations.
With groupingBy, you can use a value transformation function to perform more complex aggregations. Here is an example of using fold to create a custom grouping operation.
1data class Product(val name: String, val category: String, val price: Double) 2 3val products = listOf( 4 Product("Laptop", "Electronics", 1200.0), 5 Product("Phone", "Electronics", 800.0), 6 Product("T-shirt", "Clothing", 20.0), 7 Product("Jeans", "Clothing", 40.0) 8) 9 10val totalPricesByCategory = products.groupingBy { it.category } 11 .fold(0.0) { accumulator, element -> accumulator + element.price } 12 13println(totalPricesByCategory)
Output:
1{Electronics=2000.0, Clothing=60.0}
Here, the groupingBy method is used to create a grouping object, and the fold function is applied to calculate the total prices for each category.
You need a quick, in-memory grouping of elements.
You are only interested in the grouped elements without additional operations.
The result needs to be accessed multiple times and remains static.
You want to perform operations like count, fold, or aggregate on grouped data.
You need to optimize memory usage and delay computation until necessary.
You are working with large datasets where only the grouping structure is important until the final result is calculated.
In this article on "Kotlin GroupingBy vs GroupBy," we explored the differences between the groupBy and groupingBy functions in Kotlin and their respective use cases. While both are used for grouping collection elements, groupBy is more straightforward, returning a Map<K, List<V>>
directly, making it suitable for simpler tasks.
On the other hand, groupingBy provides a Grouping object, allowing more flexibility for complex operations like aggregation and transformation using functions such as fold and eachCount. The choice between groupBy and groupingBy depends on the specific requirements of your task, such as performance, memory usage, and the need for custom operations. Understanding these distinctions will help you use Kotlin’s powerful grouping capabilities more effectively in your projects.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.