Kotlin Data Class – Tutorial
Wirst du müde davon, tausende Zeilen Code für deine POJO-Datenklassen in Java zu schreiben? Jeder Java-Programmierer muss irgendwann einmal festgestellt haben, wie viele Zeilen Code er für Klassen schreiben muss, die nur einige Daten speichern sollen. Lass uns anschauen, wie eine Book.java POJO-Klasse aussieht:
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! Das sind 96 Zeilen Code nur um 5 Felder in einem Objekt zu speichern. Wir machen hier nicht viel außer Getter und Setter zu haben, toString(), equals() und hashCode() Methoden. Mit den sauberen Architekturen und der Trennung von Code-Praktiken in unseren Praktiken, müssen wir POJO-Klassen erstellen, da jedes Projekt irgendwo Daten speichern muss. Dies kann den Boilerplate-Code erhöhen. Hier kommt Kotlin zur Rettung, mit der Verwendung von Data Classes. Data Classes ist Koltins Antwort auf die Reduzierung von Boilerplate-Code. Die oben genannte POJO-Klasse kann in Kotlin folgendermaßen geschrieben werden:
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
DAS IST ES. Kotlin verwandelt 96 Zeilen Java-Code in eine einzige Zeile Code. Das ist Koltins Weg, den Boilerplate-Code in deinem Projekt zu reduzieren!
Kotlin Data Class erstellen
Folgendes sind die Anforderungen für das Erstellen einer Kotlin Data Class.
- Du musst die Klasse mit dem Schlüsselwort
data
versehen - Der primäre Konstruktor muss mindestens einen Parameter haben.
- Jeder Parameter des primären Konstruktors muss ein val oder ein var zugewiesen bekommen. Dies ist bei einer normalen Klasse nicht der Fall, wo das Angeben eines val oder var nicht zwingend ist.
- Data Classes können nicht mit abstract, open, sealed oder inner versehen werden
Eingebaute Methoden der Kotlin Data Class
Eine Kotlin Data Class erstellt automatisch die folgenden Funktionen für dich.
- equals() und hashCode()
- toString() in der Form „Book(name=JournalDev, authorName=Anupam)“
- componentN() Funktionen für jeden der Parameter in der angegebenen Reihenfolge. Dies ist bekannt als Zerlegungserklärungen.
- copy()
Merkmale der Kotlin Data Class
Folgend sind einige Merkmale, die eine Data Class bietet.
- Um einen parameterlosen Konstruktor zu erstellen, gib Standardwerte für jeden der Parameter im primären Konstruktor an.
- Eine Data Class erlaubt Vererbung (Keine Notwendigkeit, das Schlüsselwort open zu erwähnen).
- Du kannst explizite Implementierungen für die Funktionen equals(), hashCode() und toString() bereitstellen
- Explizite Implementierungen für copy() und componentN() Funktionen sind nicht erlaubt.
- Wir können die Sichtbarkeit der Getter und Setter steuern, indem wir die Sichtbarkeitsmodifikatoren im Konstruktor wie unten gezeigt angeben.
data class Book(var name: String,private var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
Ein val Parameter wird keinen Setter implizit definiert haben (kann auch nicht explizit gemacht werden!)
Standard- und benannte Argumente in Data Class
Folgend ist unsere Data Class:
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
Keiner der Parameter hat einen Standardwert gesetzt. Also müssen wir ein Argument für jeden von ihnen bei der Instantiierung setzen, wie unten gezeigt.
fun main(args: Array) {
val book = Book("Android Tutorials","Anupam", 1234567, 4.5f, 1000)
}
Lass uns ein paar Standardargumente setzen und sehen, wie sich die Instantiierung ändert.
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)
book = Book("Kotlin")
book = Book("Swift",downloads = 500)
book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
book = Book("Python","Shubham",rating = 5f)
}
Anstatt jedes Argument zu setzen, können wir nur die nicht-standardmäßigen und diejenigen setzen, die wir möchten, indem wir das benannte Argument verwenden. Mit Benannten Argumenten können wir das 5. Argument als das zweite setzen, indem wir explizit den Parameternamen gefolgt von = angeben. So wird das Leben viel einfacher!
Kotlin Data Class toString() Methode
Die toString() wird implizit erstellt und druckt die Argumentnamen und -labels für die Instanz wie unten gezeigt.
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())
}
Hinweis: Die print-Funktion fügt implizit ein toString() hinzu.
Kotlin Data Class copy() Methode
Die Copy-Funktion wird verwendet, um eine Kopie einer Instanz der Data Class mit einigen modifizierten Eigenschaften zu erstellen. Es wird empfohlen, val Parameter im Konstruktor der Data Classes zu verwenden, um unveränderliche Eigenschaften einer Instanzen zu nutzen. Unveränderliche Objekte sind einfacher bei der Arbeit mit Mehrfadenanwendungen. Daher, um eine Kopie eines unveränderlichen Objekts zu erstellen, indem nur einige der Eigenschaften geändert werden, ist die copy() Funktion praktisch.
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)
}
//Following is printed in the console.
//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
Kotlin Data Class equals() und hashCode()
Die hashCode() Methode gibt den Hash-Code für das Objekt zurück. Wenn zwei Objekte gleich sind, produziert hashCode() das gleiche Integer-Ergebnis. Daher gibt equals() wahr zurück, wenn der hashCode() gleich ist, sonst gibt es falsch zurück.
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")
}
//Following is printed in the console.
//Hashcode is 649213087
//Hashcode is 1237165820
//Hashcode is 649213087
//copyBook and book are equal
//newBook and book are NOT equal
Die ersten und dritten Objekt-Hashcodes sind gleich, daher sind sie gleich. Hinweis: Die equals() Methode entspricht == in Kotlin.
Zerlegungserklärungen
Die componentN() Funktion ermöglicht uns den Zugriff auf jedes der Argumente, die im Konstruktor angegeben sind, in der angegebenen Reihenfolge. N ist die Anzahl der Parameter im Konstruktor.
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.component1()) //Android tutorials
println(book.component2()) //Anupam
println(book.component3()) //1234567
println(book.component4()) //4.5
println(book.component5()) //1000
}
Zerlegungserklärungen ermöglichen es uns, auf die Argumente als Eigenschaften vom Klassenobjekt zuzugreifen, wie unten gezeigt.
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)
val (n,a,date,rating,downloads) = book
}
Hinweis: Wenn ein Sichtbarkeitsmodifikator wie private auf eines der Argumente gesetzt ist, kann es in der obigen Funktion nicht zugegriffen werden.
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) {
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
}
Das ist alles für einen schnellen Überblick über Kotlin Data Classes.