Data classes are the idiomatic way to model DTOs, API payloads and value objects in one line.
Mark a class data and the compiler generates the boilerplate from the properties in its primary constructor:
data class User(val name: String, val age: Int)equals/hashCodecompare property values, so twoUser("Ada", 36)are equal and work as map keys or in sets.toStringgivesUser(name=Ada, age=36).copy(age = 37)creates a modified copy, leaving the original untouched: the idiomatic way to "change" immutable data.component1(),component2()enable destructuring:val (name, age) = user.
Requirements: the primary constructor needs at least one val/var parameter, and data classes can't be open or abstract. Only properties in the primary constructor take part in equality and toString; properties declared in the body are ignored.
Use val properties to keep instances immutable; copy is shallow, so a MutableList inside is shared between copies.
Destructuring also works in loops and lambdas: for ((k, v) in map), pairs.map { (a, b) -> a + b }. Use _ for unused components.
Kotlin's standard Pair and Triple are data classes too, but a named data class almost always reads better. For single-value wrappers without allocation overhead, see value classes (Advanced).
Example
data class User(val name: String, val age: Int, val tags: List<String> = emptyList())
fun main() {
val a = User("Ada", 36)
val b = User("Ada", 36)
println(a == b) // true (structural equality)
println(a === b) // false (different objects)
println(a) // User(name=Ada, age=36, tags=[])
val older = a.copy(age = 37)
println("${a.age} ${older.age}") // 36 37
val (name, age) = older
println("$name is $age") // Ada is 37
val users = setOf(a, b, older)
println(users.size) // 2
val pairs = listOf(User("Bo", 20), User("Cy", 30))
println(pairs.map { (n, _) -> n.lowercase() }) // [bo, cy]
}Remember
- data generates equals, hashCode, toString, copy and componentN
- Only primary constructor properties count
- copy(...) makes modified shallow copies
- Destructure with val (a, b) = obj
Watch out for
- Declaring a property in the class body and expecting it to be part of equals.