Data Class Basics

What You Get for Free

Many classes exist only to hold data: a user, a product, an API response. Mark them data class and the compiler generates, from the properties in the primary constructor:

  • toString() - readable text like User(id=1, name=Asha)
  • equals() / hashCode() - two objects with the same values are equal
  • copy() - a copy with some values changed
  • component1(), component2()... - for destructuring

Normal Class vs Data Class

Example

class PlainUser(val id: Int, val name: String)
data class User(val id: Int, val name: String)

fun main() {
    val p1 = PlainUser(1, "Asha")
    val p2 = PlainUser(1, "Asha")
    println(p1 == p2)                     // false: compares references
    println(p1.toString().startsWith("PlainUser@"))  // ClassName@hash

    val u1 = User(1, "Asha")
    val u2 = User(1, "Asha")
    println(u1 == u2)                     // true: compares values
    println(u1)                           // readable toString
    println(setOf(u1, u2).size)           // equal objects are de-duplicated
}

Output

false
true
true
User(id=1, name=Asha)
1

== vs ===

== calls equals() (structural equality). === checks whether two variables point to the same object (referential equality).

Example

data class Point(val x: Int, val y: Int)

fun main() {
    val a = Point(1, 2)
    val b = Point(1, 2)
    val c = a
    println("a == b : ${a == b}")
    println("a === b: ${a === b}")
    println("a === c: ${a === c}")
}

Output

a == b : true
a === b: false
a === c: true