In diesem Tutorial werden wir uns Kotlin Data Class ansehen. Wenn Sie den Beitrag zu Kotlin-Klassen noch nicht gelesen haben, empfehlen wir Ihnen, dies vor dem Fortfahren zu tun.
Kotlin Data Class
Werden Sie es leid, Tausende von Codezeilen für Ihre POJO-Datenklassen in Java zu schreiben? Jeder Java-Programmierer hat irgendwann einmal die Anzahl der Codezeilen bemerkt, die er für Klassen schreiben muss, die nur einige Daten speichern müssen. Schauen wir uns an, 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 +
'}';
}
}
WOW! Das sind 96 Codezeilen, um nur 5 Felder in einem Objekt zu speichern. Hier machen wir nicht viel mehr, als Getter-Setter, toString()
, equals()
und hashCode()
Methoden zu haben. Mit den sauberen Architekturen und der Trennung von Codepraktiken in unseren Praktiken müssen wir POJO-Klassen erstellen, da jedes Projekt Daten irgendwo speichern muss. Dies kann den Boilerplate-Code erhöhen. Hier kommt Kotlin zur Rettung, mit der Verwendung von Data Classes. Data Classes sind die Antwort von Kotlin 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 war’s. Kotlin verwandelt einen 96 Zeilen Java-Code in eine einzige Codezeile. Das ist die Art und Weise von Kotlin, den Boilerplate-Code in Ihrem Projekt zu reduzieren!
Erstellen einer Kotlin-Datenklasse
Folgende Anforderungen müssen für die Erstellung einer Kotlin-Datenklasse erfüllt werden.
- Sie müssen die Klasse mit dem Schlüsselwort
data
versehen. - Der primäre Konstruktor muss mindestens einen Parameter haben.
- Jeder Parameter des primären Konstruktors muss mit einem
val
odervar
versehen sein. Dies ist im Gegensatz zu einer normalen Klasse, bei der die Angabe vonval
odervar
nicht zwingend erforderlich ist. - Datenklassen können nicht mit
abstract
,open
,sealed
oderinner
versehen werden.
Eingebaute Methoden für Kotlin-Datenklassen
Kotlin-Datenklassen erstellen automatisch die folgenden Funktionen für Sie.
equals()
undhashCode()
toString()
in der Form"Buch(name=JournalDev, authorName=Anupam)"
componentN()
-Funktionen für jeden Parameter in der angegebenen Reihenfolge. Dies wird als Destrukturierungsdeklarationen bezeichnet.copy()
Merkmale von Kotlin-Datenträgerklassen
Im Folgenden finden Sie einige Funktionen, die eine Datenträgerklasse bietet.
-
Um einen parameterlosen Konstruktor zu erstellen, geben Sie für jeden der Parameter im primären Konstruktor Standardwerte an.
-
Eine Datenträgerklasse ermöglicht die Vererbung (es ist nicht erforderlich, das Schlüsselwort
open
anzugeben). -
Sie können explizite Implementierungen für die Funktionen
equals()
hashCode()
undtoString()
bereitstellen. -
Explizite Implementierungen für die Funktionen
copy()
undcomponentN()
sind nicht erlaubt. -
Wir können die Sichtbarkeit der Getter und Setter kontrollieren, indem wir die Sichtbarkeitsmodifikatoren im Konstruktor wie unten angezeigt angeben.
Datenträgerklasse Buch(var name: String, private var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
-
Ein Val-Parameter hat implizit keinen Setter definiert (kann auch nicht explizit gemacht werden!).
Standard- und benannte Argumente in der Datensklasse
Hier ist unsere Datensklasse:
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
Keine der Parameter hat einen Standardwert. Daher müssen wir bei der Instantiierung ein Argument für jeden von ihnen setzen, wie unten gezeigt.
fun main(args: Array<String>) {
val book = Book("Android Tutorials","Anupam", 1234567, 4.5f, 1000)
}
Lassen Sie uns einige Standardargumente festlegen 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<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)
}
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 festlegen, indem wir den Parameternamen ausdrücklich angeben, gefolgt von =
. Das Leben ist so einfacher auf diese Weise!
Kotlin Data Class toString() Methode
Die toString()-Methode wird implizit erstellt und gibt die Argumentnamen und Beschriftungen für die Instanz wie unten gezeigt aus.
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())
}
//Folgendes wird in der Konsole gedruckt.
//Buch(Name=Android-Tutorials, AutorName=Anupam, zuletztGeändert=1234567, Bewertung=4,5, Downloads=1000)
//Buch(Name=Kotlin, AutorName=Anupam, zuletztGeändert=1234567, Bewertung=5,0, Downloads=1000)
//Buch(Name=Swift, AutorName=Anupam, zuletztGeändert=1234567, Bewertung=5,0, Downloads=500)
//Buch(Name=Java, AutorName=Pankaj, zuletztGeändert=1234567, Bewertung=5,0, Downloads=1000)
//Buch(Name=Python, AutorName=Shubham, zuletztGeändert=1234567, Bewertung=5,0, Downloads=1000)
Hinweis: Die print
-Funktion fügt implizit eine toString()-Methode hinzu.
Kotlin Data Class copy() Methode
Die Copy-Funktion wird verwendet, um eine Kopie einer Instanz der Datenklasse mit einigen geänderten Eigenschaften zu erstellen. Es wird empfohlen, val-Parameter im Konstruktor von Datenklassen zu verwenden, um unveränderliche Eigenschaften von Instanzen zu verwenden. Unveränderliche Objekte sind einfacher bei der Arbeit mit mehrfädigen Anwendungen. Daher ist die Verwendung der copy()
-Funktion praktisch, um eine Kopie eines unveränderlichen Objekts zu erstellen, indem nur wenige Eigenschaften geändert werden.
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)
}
//Folgendes wird in der Konsole gedruckt.
//Buch(Name=Android-Tutorials, AutorName=Anupam, zuletztGeändert=1234567, Bewertung=4,5, Downloads=1000)
//Buch(Name=Kotlin, AutorName=Anupam, zuletztGeändert=1234567, Bewertung=4,5, Downloads=1000)
Kotlin Data Class equals() und hashCode()
Die Methode hashCode()
liefert den Hashcode für das Objekt zurück. Wenn zwei Objekte gleich sind, erzeugt hashCode()
dasselbe Integer-Ergebnis. Daher gibt equals()
true zurück, wenn hashCode()
gleich ist, andernfalls 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")
}
//Folgendes wird in der Konsole gedruckt.
//Hashcode ist 649213087
//Hashcode ist 1237165820
//Hashcode ist 649213087
//copyBook und book sind gleich
//newBook und book sind NICHT gleich
Die Hashcodes des ersten und dritten Objekts sind gleich, daher sind sie gleich. Hinweis: Die Methode equals()
entspricht ==
in Kotlin.
Destructuring-Deklarationen
Die Funktion componentN()
ermöglicht den Zugriff auf jeden im Konstruktor angegebenen Parameter in der festgelegten 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<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
}
Deklarationen von Destrukturierungen ermöglichen den Zugriff auf die Argumente als Eigenschaften des Klassenobjekts, 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<String>) {
val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
val (n,a,date,rating,downloads) = book
}
Hinweis: Wenn ein Sichtbarkeitsmodifizierer wie private auf eines der Argumente festgelegt 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<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
}
Das war alles für eine schnelle Zusammenfassung zu Kotlin-Datenträgern. Referenzen: Kotlin-Dokumentation
Source:
https://www.digitalocean.com/community/tutorials/kotlin-data-class