Menu
Coddy logo textTech

Classi di dati

Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 32 di 57.

Una classe data è una classe il cui compito principale è contenere dati. Il modificatore data fa generare al compilatore toString(), equals(), hashCode(), copy() e componentN() a partire dalle proprietà del costruttore primario:

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

All'interno di main:

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

Output:

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

Senza data, println mostra il nome della classe e un codice hash come Point@1b6d3586, e due oggetti con gli stessi valori non sono uguali. copy() crea un nuovo oggetto con alcune proprietà modificate e lascia l'originale invariato, quindi una classe dati con proprietà val funziona come valore immutabile:

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

Dentro main:

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

Output:

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

Le dichiarazioni di destrutturazione scompongono un oggetto in variabili: val (x, y) = point chiama component1() e component2() generati, nell’ordine del costruttore. Funziona anche nei cicli for e nei parametri delle lambda, mentre _ salta una proprietà:

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

All’interno di 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")

Output:

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

Partecipano solo le proprietà del costruttore primario: una proprietà dichiarata nel corpo della classe viene esclusa da toString, equals, hashCode e copy. Una classe dati richiede almeno un parametro del costruttore e ogni parametro deve essere un val o un var:

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

All'interno di main:

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

Output:

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

Sfida

Facile

Rendi Book una data class, così verrà stampata e confrontata in base al valore. Poi completa tre funzioni: parse(line) trasforma Dune;Herbert;1965 in un Book, newEdition(book, year) restituisce una copia con il nuovo anno e (new edition) aggiunto al titolo, e describe(book) restituisce Dune by Herbert, 1965 usando una dichiarazione di destrutturazione.

Il codice fornito analizza ogni riga di input, stampa ogni libro, il numero di duplicati, la nuova edizione del primo libro (anno 2024) e una descrizione di ogni libro distinto.

Il tuo codice va inserito in Book.kt e BookTools.kt. Main.kt contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

fun main() {
    // Codice di input/output fornito: lascialo così com'è
    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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Playground Kotlin