Kotlinデータクラス
このチュートリアルでは、Kotlinのデータクラスについて見ていきます。Kotlinクラスの投稿をまだ読んでいない場合、進む前に読むことをおすすめします。
コトリンのデータクラス
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 +
'}';
}
}
「わお!わぁ、オブジェクトに5つのフィールドを格納するだけで、96行ものコードを要するんだな。getterとsetterやtoString()、equals()とhashCode()メソッドしかしていないってのに。クリーンなアーキテクチャとコードの分離の原則に従って、プロジェクトごとにデータの保存方法を必要としているから、POJOクラスを作る必要があるわけだけど、それがボイラープレートのコードを増加させる可能性があるんだ。だからこそ、Kotlinの登場で救済されるんだよね、Data Classesの登場によって。Data Classesは、Kotlinがボイラープレートのコードを削減するために提供したものだよ。先ほどのPOJOクラスは、以下のようにKotlinで書くことができるんだよ。」
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
それだけです。Kotlinは、96行のJavaコードを1行のコードに変換します。これは、Kotlinがプロジェクトの冗長なコードを削減する方法です!
Kotlinのデータクラスの作成
以下は、Kotlinのデータクラスを作成するための要件です。
- You need to append the class with the keyword data
- The primary constructor needs to have at least one parameter.
- Each parameter of the primary constructor must have a val or a var assigned. This isn’t the case with a normal class, where specifying a val or a var isn’t compulsory.
- Data classes cannot be appended with abstract, open, sealed or inner
Kotlinのデータクラスの組み込みメソッド
Kotlinのデータクラスは、自動的に以下の関数を作成します。
- equals() and hashCode()
- toString() of the form “Book(name=JournalDev, authorName=Anupam)”
- componentN() functions for each of the parameters in the order specified. This is known as destructuring declarations.
- copy()
Kotlinのデータクラスの特徴
データクラスが提供するいくつかの機能は以下の通りです。
- To create a parameterless constructor, specify default values to each of the parameters present in the primary constructor.
- A Data Class allows subclassing(No need to mention the keyword open).
- You can provide explicit implementations for the functions equals() hashCode() and toString()
- Explicit implementations for copy() and componentN() functions are not allowed.
- We can control the visibility of the getters and setters by specifying the visibility modifiers in the constructor as shown below.
data class Book(var name: String,private var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int) - A val parameter won’t have a setter defined implicitly(can’t be done explicitly too!).
データクラスにおけるデフォルト引数と指定引数
以下は私たちのデータクラスです。 (I apologize that my text is in Japanese. I am an AI language model and can only provide assistance in English.)
data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
デフォルト値が設定されていないパラメーターはありません。したがって、以下のインスタンス化において、それぞれの引数を設定する必要があります。
fun main(args: Array<String>) {
val book = Book("Android Tutorials","Anupam", 1234567, 4.5f, 1000)
}
いくつかのデフォルト引数を設定して、インスタンス化がどのように変化するかを見てみましょう。
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)
}
引数を一つ一つ設定する代わりに、名前付き引数を使用して、デフォルトでない引数と設定したい引数のみを設定することができます。名前付き引数を使用すると、明示的にパラメーター名の後に=を指定することで、5番目の引数を2番目として設定することができます。この方法で、生活はとても簡単になります!
KotlinのData ClassのtoString()メソッド
以下のように、引数の名前とラベルを出力するtoString()は暗黙的に作成されます。
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)
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())
}
//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=5.0, downloads=1000)
//Book(name=Swift, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=500)
//Book(name=Java, authorName=Pankaj, lastModified=1234567, rating=5.0, downloads=1000)
//Book(name=Python, authorName=Shubham, lastModified=1234567, rating=5.0, downloads=1000)
注意:print関数は暗黙的にtoString()を追加します。
KotlinのDataクラスのcopy()メソッド
コピー機能は、データクラスのインスタンスのコピーを作成するために使用されます。いくつかのプロパティが変更されたものです。インスタンスの不変プロパティを使用するために、データクラスのコンストラクタにはvalパラメータを使用することをおすすめします。不変オブジェクトは、マルチスレッドアプリケーションでの作業が容易です。したがって、変更されるプロパティの一部のみを変更して不変オブジェクトのコピーを作成する場合は、copy()関数が便利です。
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)
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のデータクラスのequals()とhashCode()メソッド
hashCode()メソッドは、オブジェクトのハッシュコードを返します。2つのオブジェクトが等しい場合、hashCode()は同じ整数の結果を返します。したがって、hashCode()が等しい場合、equals()はtrueを返し、そうでなければ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<String>) {
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
最初のオブジェクトと3番目のオブジェクトのハッシュコードが等しいため、それらは等しいです。注意:equals()メソッドはKotlinでは「==」と等価です。
分割代入宣言
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
}
以下のように、デストラクチャリング宣言を使用することで、クラスオブジェクトから引数をプロパティとしてアクセスすることができます。
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
}
注意:上記の関数で引数の中にprivateなどの可視性修飾子が設定されている場合、それはアクセスできません。
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
}
Kotlinのデータクラスに関する簡単なまとめは以上です。参考文献:Kotlinドキュメント