SyntaxStudy
Sign Up
Kotlin Data Classes Fundamentals
Kotlin Beginner 1 min read

Data Classes Fundamentals

A data class is a class whose primary purpose is to hold data. Prefixing a class with data instructs the compiler to generate equals(), hashCode(), toString(), and copy() based on the properties declared in the primary constructor. This eliminates an entire category of boilerplate that plagues Java code. The generated equals() performs structural comparison: two data class instances with identical property values are considered equal regardless of reference identity. hashCode() is consistent with equals(), making data classes safe to use as keys in sets and maps. copy() creates a new instance with some properties overridden, leaving the rest unchanged. This is the idiomatic way to produce a modified version of an immutable data class without mutation.
Example
data class Address(
    val street: String,
    val city: String,
    val zip: String,
)

data class User(
    val id: Int,
    val name: String,
    val email: String,
    val address: Address,
)

fun main() {
    val addr  = Address("123 Main St", "Springfield", "12345")
    val user1 = User(1, "Alice", "alice@example.com", addr)

    // toString — auto-generated, deeply nested
    println(user1)

    // Structural equality
    val user2 = User(1, "Alice", "alice@example.com", addr)
    println(user1 == user2)    // true
    println(user1 === user2)   // false — different objects

    // copy — change only specific fields
    val updatedUser = user1.copy(
        email   = "alice@newdomain.com",
        address = addr.copy(city = "Shelbyville"),
    )
    println(updatedUser)

    // Destructuring
    val (id, name, email) = user1
    println("id=$id  name=$name  email=$email")

    // Works as map key (hashCode consistent with equals)
    val userMap = mapOf(user1 to "active", updatedUser to "pending")
    println(userMap[user2])   // active (user2 == user1)
}