English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Clases de datos (Data) en Kotlin

In this article, you will learn how to create data classes in Kotlin. You will also learn about the requirements that data classes must meet and their standard features.

You may encounter a situation where you need to create a class that is only used to store data. In this case, you can mark the class as data to create a data class. For example,

data class Person(val name: String, var age: Int)

For this class, the compiler will automatically generate:

  • copy() function, equals() and hashCode() pairs, and the toString() form of the primary constructor

  • componentN() function

Before discussing these functions in detail, let's discuss the requirements that a data class must meet.

Requirements for Kotlin data classes

The requirements are as follows:

  • The primary constructor must have at least one parameter.

  • The parameters of the primary constructor must be marked as val (read-only) or var (read-write).

  • The class cannot be open, abstract, inner, or sealed.

  • The class can extend other classes or implement interfaces. If you are using1.1Previous versions of Kotlin required the class to implement the interface.

Ejemplo: Clase de datos Kotlin

data class User(val nombre: String, val edad: Int)
fun main(args: Array<String>) {
    val jack = User("jack", 29)
    println("nombre = ${jack.nombre}")
    println("edad = ${jack.edad}")
}

La salida cuando se ejecuta el programa es:

nombre = jack
age = 29

Cuando declara una clase de datos, el compilador genera automáticamente varias funciones en el fondo, como toString(), equals(), hashCode(), etc. Esto ayuda a mantener la concisión del código. Si usa Java, necesita escribir mucho código de plantilla.
Vamos a usar las siguientes funciones:

La función copy() - Copia

Para las clases de datos, puede usar la función copy() para crear copias de objetos con propiedades diferentes. Su mecanismo de funcionamiento es el siguiente:

data class User(val nombre: String, val edad: Int)
fun main(args: Array<String>) {
    val u1 = User("John", 29)
   
    //Crear objetos usando la función de copia
    val u2 = u1.copy(nombre = "Randy")
    println("u1: nombre = ${u1.nombre}, nombre = ${u1.edad")
    println("u2: nombre = ${u2.nombre}, nombre = ${u2.edad")
}

La salida cuando se ejecuta el programa es:

u1: nombre = John, nombre = 29
u2: nombre = Randy, nombre = 29

El método toString() - Devuelve una cadena

La función toString() devuelve la representación de cadena del objeto.

data class User(val nombre: String, val edad: Int)
fun main(args: Array<String>) {
    val u1 = User("John", 29)
    println(u1.toString())
}

La salida cuando se ejecuta el programa es:

User(nombre = John, edad =29)

hashCode() y equals()

El método hasCode() devuelve el código de hash del objeto. Si dos objetos son iguales, hashCode() generará el mismo resultado numérico.

Si dos objetos son iguales (hashCode() es el mismo), equals() devuelve true. Si los objetos no son iguales, equals() devuelve false.

data class User(val nombre: String, val edad: Int)
fun main(args: Array<String>) {
    val u1 = User("John", 29)
    val u2 = u1.copy()
    val u3 = u1.copy(nombre = "Amanda")
    println("u1 hashCode = ${u1.hashCode()")
    println("u2 hashCode = ${u2.hashCode()")
    println("u3 hashCode = ${u3.hashCode()")
    if (u1.equals(u2) == true)
        println("u1 es igual a u2.")
    else
        println("u1 no es igual a u2.")
    if (u1.equals(u3) == true)
        println("u1 es igual a u3.")
    else
        println("u1 no es igual a u3.")
}

La salida cuando se ejecuta el programa es:

u1 hashCode = 71750738
u2 hashCode = 71750738
u3 hashCode = 771732263
u1 es igual a u2.
u1 no es igual a u3.

Declaración de desestructuración

Puede usar la declaración de desestructuración para descomponer un objeto en varias variables. Por ejemplo:

data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
    val u1 = User("John", 29, "Male")
    val (nombre, edad, genero) = u1
    println("nombre = $name")
    println("edad = $age")
    println("gender = $gender")
}

La salida cuando se ejecuta el programa es:

name = John
age = 29
gender = Male

Esto es posible porque el compilador genera automáticamente el método component() para todas las propiedades de la clase de datos. Por ejemplo:

data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
    val u1 = User("John", 29, "Male")
    println(u1.component1())     // John
    println(u1.component2())     // 29  
    println(u1.component3())     // "Male"
}

La salida cuando se ejecuta el programa es:

John
29
Male