In questo tutorial, esamineremo la Kotlin Data Class. Se non hai letto il post su Classi Kotlin, ti consigliamo di farlo prima di procedere.
Kotlin Data Class
Ti stanchi di scrivere migliaia di righe di codice per le tue classi dati POJO in Java? Ogni programmatore Java a un certo punto deve aver preso nota del numero di righe di codice necessarie per classi che devono solo memorizzare alcuni dati. Vediamo come appare una classe POJO
Book.java
:
public class Book {
private String name;
private String authorName;
private long lastModifiedTimeStamp;
private float rating;
private int downloads;
public Book(String name, String authorName, long lastModified, float rating, int downloads) {
this.name = name;
this.authorName = authorName;
this.lastModifiedTimeStamp = lastModified;
this.rating = rating;
this.downloads = downloads;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public long getLastModifiedTimeStamp() {
return lastModifiedTimeStamp;
}
public void setLastModifiedTimeStamp(long lastModifiedTimeStamp) {
this.lastModifiedTimeStamp = lastModifiedTimeStamp;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
public int getDownloads() {
return downloads;
}
public void setDownloads(int downloads) {
this.downloads = downloads;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book that = (Book) o;
if (downloads != that.downloads)
return false;
if (name != null ? !name.equals(that.name) :
that.name != null) {
return false;
}
return authorName != null ?
authorName.equals(that.authorName) :
that.authorName == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (authorName != null ?
authorName.hashCode() : 0);
result = 31 * result + downloads;
return result;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + authorName + '\'' +
", lastModifiedTimestamp='" + lastModifiedTimeStamp + '\'' +
", rating='" + rating + '\'' +
", downloads=" + downloads +
'}';
}
}
WOAH! Sono 96 righe di codice solo per memorizzare 5 campi in un oggetto. Non stiamo facendo molto qui oltre ad avere getter setter, toString()
, equals()
e metodi hashCode()
. Con le architetture pulite e la separazione delle pratiche di codice nelle nostre pratiche, dobbiamo creare classi POJO poiché ogni progetto ha bisogno di memorizzare dati da qualche parte. Questo può aumentare il codice boilerplate. Ecco dove entra in gioco Kotlin, con l’uso delle Data Classes. Le Data Classes sono la risposta di Kotlin per ridurre il codice boilerplate. La classe POJO sopra può essere scritta in Kotlin nel seguente modo:
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
ECCO. Kotlin converte un codice java di 96 righe in una singola riga di codice. Questo è il modo di Kotlin per ridurre il codice boilerplate nel tuo progetto!
Creazione della classe di dati Kotlin
Ecco i requisiti per la creazione di una classe di dati Kotlin.
- È necessario aggiungere la parola chiave
data
alla classe - Il costruttore principale deve avere almeno un parametro.
- Ogni parametro del costruttore principale deve essere assegnato con
val
ovar
. Questo non è il caso di una classe normale, dove specificareval
ovar
non è obbligatorio. - Le classi di dati non possono essere estese con
abstract
,open
,sealed
oinner
Metodi integrati della classe di dati Kotlin
La classe di dati Kotlin crea automaticamente le seguenti funzioni per te.
equals()
ehashCode()
toString()
della forma"Libro(nome=JournalDev, nomeAutore=Anupam)"
- Funzioni
componentN()
per ciascun parametro nell’ordine specificato. Questo è noto come dichiarazioni di destrutturazione. copy()
Funzionalità della classe di dati Kotlin
Ecco alcune funzionalità che una classe di dati fornisce.
-
Per creare un costruttore senza parametri, specificare valori predefiniti per ciascuno dei parametri presenti nel costruttore primario.
-
Una classe di dati consente la sottoclasse (non è necessario menzionare la parola chiave
open
). -
Puoi fornire implementazioni esplicite per le funzioni
equals()
hashCode()
etoString()
-
Non sono consentite implementazioni esplicite per le funzioni
copy()
ecomponentN()
. -
Possiamo controllare la visibilità dei getter e dei setter specificando i modificatori di visibilità nel costruttore come mostrato di seguito.
data class Libro(var nome: String, private var nomeAutore: String, var ultimaModifica: Long, var valutazione: Float, var download: Int)
-
Un parametro val non avrà un setter definito implicitamente (non può essere fatto in modo esplicito!).
Argomenti predefiniti e nominati in una classe di dati
Di seguito è riportata la nostra classe di dati:
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
Nessuno dei parametri ha un valore predefinito impostato. Quindi dobbiamo impostare un argomento per ciascuno di essi nell’istanza come mostrato di seguito.
fun main(args: Array<String>) {
val book = Book("Android Tutorials","Anupam", 1234567, 4.5f, 1000)
}
Impostiamo alcuni argomenti predefiniti e vediamo come cambia l’istanza.
data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)
fun main(args: Array<String>) {
var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
book = Book("Kotlin")
book = Book("Swift",downloads = 500)
book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
book = Book("Python","Shubham",rating = 5f)
}
Invece di impostare ogni argomento, possiamo impostare solo quelli non predefiniti e quelli che desideriamo utilizzare utilizzando l’argomento nominato. Utilizzando gli argomenti nominati, possiamo impostare il quinto argomento come il secondo specificando esplicitamente il nome del parametro seguito da =
. La vita è così più semplice in questo modo!
Metodo toString() della classe di dati di Kotlin
Il metodo toString() viene creato implicitamente e stampa i nomi e le etichette degli argomenti per l’istanza come mostrato di seguito.
data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)
fun main(args: Array) {
var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
println(book)
book = Book("Kotlin")
println(book)
book = Book("Swift",downloads = 500)
println(book)
book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
println(book.toString())
book = Book("Python","Shubham",rating = 5f)
println(book.toString())
}
//Di seguito viene stampato nella console.
//Libro(nome=Android tutorials, nomeAutore=Anupam, ultimaModifica=1234567, valutazione=4.5, download=1000)
//Libro(nome=Kotlin, nomeAutore=Anupam, ultimaModifica=1234567, valutazione=5.0, download=1000)
//Libro(nome=Swift, nomeAutore=Anupam, ultimaModifica=1234567, valutazione=5.0, download=500)
//Libro(nome=Java, nomeAutore=Pankaj, ultimaModifica=1234567, valutazione=5.0, download=1000)
//Libro(nome=Python, nomeAutore=Shubham, ultimaModifica=1234567, valutazione=5.0, download=1000)
Nota: La funzione print
aggiunge implicitamente un metodo toString()
.
Metodo copy() della classe di dati Kotlin
La funzione Copy viene utilizzata per creare una copia di un’istanza della classe di dati con alcune proprietà modificate. Si consiglia di utilizzare parametri val nella costruzione di classi di dati per utilizzare proprietà immutabili delle istanze. Gli oggetti immutabili sono più facili da gestire in applicazioni multithreading. Quindi, per creare una copia di un oggetto immutabile modificando solo alcune proprietà, la funzione copy()
è utile.
data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
fun main(args: Array) {
val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
println(book)
val newBook = book.copy(name = "Kotlin")
println(newBook)
}
//Di seguito viene stampato nella console.
//Libro(nome=Android tutorials, nomeAutore=Anupam, ultimaModifica=1234567, valutazione=4.5, download=1000)
//Libro(nome=Kotlin, nomeAutore=Anupam, ultimaModifica=1234567, valutazione=4.5, download=1000)
Classe di Dati Kotlin equals() e hashCode()
Il metodo hashCode()
restituisce il codice hash per l’oggetto. Se due oggetti sono uguali, hashCode()
produce lo stesso risultato intero. Quindi, equals()
restituisce true se il hashCode()
è uguale, altrimenti restituisce false.
data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
fun main(args: Array) {
val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
println("Hashcode is ${book.hashCode()}")
val newBook = book.copy(name = "Kotlin")
println("Hashcode is ${newBook.hashCode()}")
val copyBook = book.copy()
println("Hashcode is ${copyBook.hashCode()}")
if(copyBook.equals(book))
println("copyBook and book are equal")
if(!book.equals(newBook))
println("newBook and book are NOT equal")
}
//Quanto segue viene stampato nella console.
//Hashcode è 649213087
//Hashcode è 1237165820
//Hashcode è 649213087
//copyBook e book sono uguali
//newBook e book NON sono uguali
Il primo e il terzo codice hash degli oggetti sono uguali, quindi sono uguali. Nota: Il metodo equals()
è equivalente a ==
in Kotlin.
Dichiarazioni di Destrutturazione
La funzione componentN()
ci consente di accedere a ciascuno degli argomenti specificati nel costruttore, nell’ordine specificato. N è il numero di parametri nel costruttore.
data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
fun main(args: Array<String>) {
val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
println(book.component1()) //Android tutorials
println(book.component2()) //Anupam
println(book.component3()) //1234567
println(book.component4()) //4.5
println(book.component5()) //1000
}
Le dichiarazioni di destrutturazione ci permettono di accedere agli argomenti come proprietà dell’oggetto della classe, come mostrato di seguito.
data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
fun main(args: Array<String>) {
val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
val (n,a,date,rating,downloads) = book
}
Nota: Se viene impostato un modificatore di visibilità come privato su uno qualsiasi degli argomenti, non può essere accessibile nella funzione sopra.
data class Book(val name: String,private val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
fun main(args: Array<String>) {
val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
val (n,a,date,rating,downloads) = book //This won't compile since authorName is private
}
Ecco tutto per un breve riassunto sulle classi di dati Kotlin. Riferimenti: Documentazione Kotlin
Source:
https://www.digitalocean.com/community/tutorials/kotlin-data-class