Skip to content
AgileLogics
4 min read

Sets and Pairs

Prerequisites: Maps

Two more ways to group values.

Sets — unique values

A set holds each value at most once. Checking whether a set contains something is very fast, even for large sets.

fun main() {
    val tags = mutableSetOf("kotlin", "android", "kotlin", "gradle")
    println(tags)
    println(tags.size)
    println("android" in tags)

    tags.add("compose")
    tags.remove("gradle")
    println(tags)

    val a = setOf(1, 2, 3, 4)
    val b = setOf(3, 4, 5)
    println(a intersect b)
    println(a union b)
    println(a subtract b)
}
[kotlin, android, gradle]
3
true
[kotlin, android, compose]
[3, 4]
[1, 2, 3, 4, 5]
[1, 2]

The duplicate "kotlin" is stored once. Sets from setOf keep insertion order.

intersect, union, and subtract are infix functions — called without a dot or parentheses, like operators.

Use a set when you only care about membership ("have we seen this before?"), and a list when order or duplicates matter.

Pairs — two values together

A Pair holds two values, which can be different types. to creates one — the same to used for maps:

fun minMax(numbers: List<Int>): Pair<Int, Int> =
    numbers.min() to numbers.max()

fun main() {
    val point = 3 to 4
    println(point.first)
    println(point)

    val (low, high) = minMax(listOf(4, 9, 1))
    println("$low to $high")
}
3
(3, 4)
1 to 9

val (low, high) = ... destructures the pair into two variables.

Pairs are handy for returning two values from a function. For anything passed around widely, a data class (Level 2) is clearer: its fields have real names instead of first and second.