Mastering Collections in Kotlin
kouta222

kouta222 @kouta222

About: Software engineer mainly frontend developing / seek for an engineer position in usa

Location:
Tokyo,japan
Joined:
Jan 21, 2024

Mastering Collections in Kotlin

Publish Date: Jun 29
2 0

Summary

Kotlin offers a powerful collection framework that is explicitly divided into read-only and mutable types, which encourages safer and more maintainable code compared to Java. In Kotlin, the three core collection types are:

  • List: An ordered collection that can contain duplicate elements.
  • Set: A collection of unique elements where the order is generally not guaranteed.
  • Map: A collection of key-value pairs, where keys are unique.

This article explains the structure of Kotlin collections, their differences, and how to use them effectively, including sample code and practical explanations.

List – Ordered and Indexable

A List is an ordered collection where the position of elements matters, and duplicates are allowed. Lists are similar to arrays, but they offer more built-in functionality.

Key Features:

  • Elements are accessed by index (list[0] for the first element).
  • Duplicates are allowed.
  • Maintains the insertion order.

Example:

fun main() {
    val numbers = listOf(1, 2, 3, 2, 4)
    println(numbers[0]) // Output: 1
    println(numbers)    // Output: [1, 2, 3, 2, 4]
}
Enter fullscreen mode Exit fullscreen mode

MutableList:
If you need to add, remove, or update elements, use MutableList.

fun main() {
    val mutableNumbers = mutableListOf(1, 2, 3)
    mutableNumbers.add(4)
    println(mutableNumbers) // Output: [1, 2, 3, 4]
}
Enter fullscreen mode Exit fullscreen mode

Why Kotlin Separates List and MutableList (Unlike Java)

In Java, even when you declare a collection as List<String>, the underlying collection can still be changed if you hold a reference to a modifiable list. This can lead to unintended side effects and bugs.

Kotlin solves this problem by:

  • Providing read-only interfaces like List and Set.
  • Forcing you to explicitly use MutableList or MutableSet when you want to change a collection.

This separation:

  • Improves code safety and predictability.
  • Makes mutability a conscious decision.
  • Encourages using val for collections to make them immutable, which leads to more stable code.

Reference: Qiita Article


Set – Unique Elements

A Set is a collection that automatically eliminates duplicates. The order is usually undefined, meaning you should not rely on element positions.

Key Features:

  • Only unique elements are allowed.

  • Order is not guaranteed.

  • Can contain null (but only one null).


fun main() {
    val uniqueNumbers = setOf(1, 2, 3, 2, 4)
    println(uniqueNumbers) // Output: [1, 2, 3, 4]
}
Enter fullscreen mode Exit fullscreen mode

MutableSet:

To modify a set (add/remove elements), use MutableSet.

fun main() {
    val mutableSet = mutableSetOf(1, 2, 3)
    mutableSet.add(4)
    mutableSet.add(2) // No effect, duplicates not allowed
    println(mutableSet) // Output: [1, 2, 3, 4]
}
Enter fullscreen mode Exit fullscreen mode

Map – Key-Value Pairs

A Map stores pairs of keys and values. Unlike List or Set, maps are not part of the Collection interface because they work with key-value structures.

Key Features:

  • Keys must be unique.

  • Values can repeat.

  • Useful for associating related data.

Example:


fun main() {
    val employeeMap = mapOf(1 to "Alice", 2 to "Bob", 3 to "Charlie")
    println(employeeMap[2]) // Output: Bob
}
Enter fullscreen mode Exit fullscreen mode

MutableMap:

Use MutableMap if you need to add, remove, or update entries.

fun main() {
    val mutableEmployeeMap = mutableMapOf(1 to "Alice", 2 to "Bob")
    mutableEmployeeMap[3] = "Charlie"
    println(mutableEmployeeMap) // Output: {1=Alice, 2=Bob, 3=Charlie}
}

Enter fullscreen mode Exit fullscreen mode

Collection Operations

Sorting Collections

Example: Sorting, Reversing, Shuffling


fun main() {
    val names = listOf("Charlie", "Alice", "Bob")
    println(names.sorted())      // Output: [Alice, Bob, Charlie]
    println(names.reversed())    // Output: [Bob, Alice, Charlie]
    println(names.shuffled())    // Output: Random order
}
Enter fullscreen mode Exit fullscreen mode

Custom Sorting with Comparator

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

fun main() {
    val people = listOf(Person("Alice", 30), Person("Bob", 25), Person("Charlie", 35))
    val sortedByAge = people.sortedBy { it.age }
    println(sortedByAge)
}
Enter fullscreen mode Exit fullscreen mode

Mapping Collections (Transformations)

Example: Transforming List Elements


fun main() {
    val numbers = listOf(1, 2, 3)
    val doubled = numbers.map { it * 2 }
    println(doubled) // Output: [2, 4, 6]
}
Enter fullscreen mode Exit fullscreen mode

Example: Mapping Keys and Values in a Map


fun main() {
    val employeeMap = mapOf(1 to "Alice", 2 to "Bob")
    val upperCaseNames = employeeMap.mapValues { it.value.uppercase() }
    println(upperCaseNames) // Output: {1=ALICE, 2=BOB}
}
Enter fullscreen mode Exit fullscreen mode

Flattening Nested Collections

When you have collections inside collections (like List>), flattening makes them a single list.


fun main() {
    val listOfSets = listOf(setOf(1, 2), setOf(3, 4))
    val flatList = listOfSets.flatten()
    println(flatList) // Output: [1, 2, 3, 4]
}
Enter fullscreen mode Exit fullscreen mode

Filtering Collections

Basic Filtering

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    val evenNumbers = numbers.filter { it % 2 == 0 }
    println(evenNumbers) // Output: [2, 4]
}
Enter fullscreen mode Exit fullscreen mode

Partitioning (Filtering with Two Groups)

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    val (even, odd) = numbers.partition { it % 2 == 0 }
    println(even) // Output: [2, 4]
    println(odd)  // Output: [1, 3, 5]
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Kotlin's collection system is powerful, expressive, and safer than many other languages thanks to its strict separation of read-only and mutable types.
By understanding how Lists, Sets, and Maps work, and learning the built-in transformation and filtering functions, you can write concise and readable Kotlin code that fully leverages the power of collections.

Reference: kotlin document

Comments 0 total

    Add comment