Menu
Coddy logo textTech

Classes de Dados

Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 32 de 57.

Uma classe de dados é uma classe cuja principal função é armazenar dados. O modificador data faz o compilador gerar toString(), equals(), hashCode(), copy() e componentN() a partir das propriedades do construtor primário:

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

Dentro de main:

val a = Point(1, 2)
val b = Point(1, 2)
println(a)
println(a == b)
println(setOf(a, b).size)

Saída:

Point(x=1, y=2)
true
1

Sem data, println exibe o nome da classe e um código hash, como Point@1b6d3586, e dois objetos com os mesmos valores não são iguais. copy() cria um novo objeto com algumas propriedades alteradas e deixa o original como está, portanto uma classe de dados com propriedades val funciona como um valor imutável:

data class User(val name: String, val email: String, val admin: Boolean = false)

Dentro de main:

val ada = User("Ada", "ada@example.com")
val boss = ada.copy(admin = true)
println(ada)
println(boss)
println(ada == boss)

Saída:

User(name=Ada, email=ada@example.com, admin=false)
User(name=Ada, email=ada@example.com, admin=true)
false

Declarações de desestruturação desempacotam um objeto em variáveis: val (x, y) = point chama os métodos component1() e component2() gerados, na ordem do construtor. Isso também funciona em laços for e parâmetros de lambda, e _ ignora uma propriedade:

data class Score(val player: String, val points: Int, val level: Int)

Dentro de main:

val scores = listOf(Score("ada", 120, 3), Score("bo", 95, 2))
for ((player, points) in scores) println("$player: $points")
val (_, bestPoints, bestLevel) = scores.maxBy { it.points }
println("best: $bestPoints at level $bestLevel")

Saída:

ada: 120
bo: 95
best: 120 at level 3

Apenas as propriedades do construtor primário participam: uma propriedade declarada no corpo da classe é deixada de fora de toString, equals, hashCode e copy. Uma classe de dados precisa de pelo menos um parâmetro de construtor, e cada parâmetro deve ser um val ou var:

data class Reading(val sensor: String, val value: Int) {
    var note = ""
}

Dentro de main:

val r1 = Reading("t1", 20)
val r2 = Reading("t1", 20)
r1.note = "checked"
println(r1)
println(r1 == r2)

Saída:

Reading(sensor=t1, value=20)
true
challenge icon

Desafio

Fácil

Faça Book ser uma classe de dados para que seja impressa e comparada por valor. Em seguida, complete três funções: parse(line) transforma Dune;Herbert;1965 em um Book, newEdition(book, year) retorna uma cópia com o novo ano e (new edition) adicionado ao título, e describe(book) retorna Dune by Herbert, 1965 usando uma declaração de desestruturação.

O código fornecido analisa cada linha de entrada, imprime cada livro, o número de duplicatas, a nova edição do primeiro livro (ano 2024) e uma descrição de cada livro distinto.

Seu código deve estar em Book.kt e BookTools.kt. Main.kt contém o código fornecido de entrada/saída e não pode ser editado.

REQUERIDO FORMATO DE SAÍDA: [Seu conteúdo traduzido aqui]

Experimente você mesmo

fun main() {
    // Código de entrada/saída fornecido: mantenha-o como está
    val input = generateSequence(::readLine).toList()
    val books = input.map { parse(it) }
    for (b in books) println(b)
    println("duplicates: ${books.size - books.distinct().size}")
    println(newEdition(books[0], 2024))
    for (b in books.distinct()) println(describe(b))
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Kotlin