Lesson 8 / 25

Data Classes

equals, hashCode, toString, copy and destructuring for free.

Value-like classes

Marking a class data makes the compiler generate equals(), hashCode(), toString(), copy() and componentN() functions from the properties in the primary constructor. Two data objects with equal properties are equal, which suits values such as DTOs, events and state. copy(field = ...) creates a modified copy, which pairs well with read-only val properties for immutable updates. componentN functions enable destructuring declarations such as val (id, name) = user. Properties declared in the class body are not part of the generated functions.

copy and destructuring

Immutable updates.

data class User(val id: Long, val name: String, val active: Boolean = true)

fun main() {
    val ada = User(1, "Ada")
    val inactive = ada.copy(active = false)      // new object, ada unchanged

    println(ada == User(1, "Ada"))               // structural equality via equals()
    println(inactive)                            // generated toString()

    val (id, name) = ada                         // destructuring via component1/2
    println("$id -> $name")

    val users = mapOf(1L to "Ada", 2L to "Linus")
    for ((key, value) in users) println("$key=$value")
}

== versus ===

In Kotlin == calls equals() (structural equality) and === checks whether two references point to the same object (referential equality).

Quick check: Which function is NOT generated for a data class?

  • `equals()`
  • `copy()`
  • `save()`
  • `component1()`
Answer

`save()` — Data classes generate equals, hashCode, toString, copy and componentN.