English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Kotlin データクラス(Data)

この記事では、Kotlinでデータクラスを作成する方法について学びます。また、データクラスが満たす必要条件や標準機能についても学びます。

こんな状況が発生することがあります:データを保存するためのクラスを作成する必要があります。その場合、データクラスとしてクラスをマークすることができます。例えば、

data class Person(val name: String, var age: Int)

このようなクラスに対して、コンパイラは自動的に生成します:

  • copy()関数、equals()とhashCode()および主要コンストラクタのtoString()の形式

  • componentN() 関数

これらの関数について詳しく説明する前に、データクラスが満たす必要条件について話しましょう。

Kotlin データクラスの要件

以下の要件があります:

  • メインコンストラクタには少なくとも1つの引数を持つ必要があります。

  • メインコンストラクタの引数はval(読み取り専用)またはvar(読み取り・書き込み)でマークする必要があります。

  • クラスはオープン、抽象的、内部、または密封であってはなりません。

  • このクラスは他のクラスを拡張したりインターフェースを実装することができます。もしあなたが使用しているのは1.1前のKotlinバージョンでは、このクラスはインターフェースを実装するだけでなくできます。

示例:Kotlin 数据类使用

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val jack = User("jack", 29)
    println("name = ${jack.name}")
    println("age = ${jack.age}")
}

このプログラムを実行すると、出力は以下のようになります:

name = jack
age = 29

当您声明一个数据类时,编译器会在后台自动生成几个函数,如toString()、equals()、hashCode()等。 这有助于保持代码的简洁性。 如果您使用Java,则需要编写大量样板代码。
让我们使用以下函数:

copy() 函数 - 复制

对于数据类,可以使用copy()函数创建具有不同属性的对象副本。 它的工作原理如下:

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val u1 = User("ジョン", 29)
   
    //使用复制函数创建对象
    val u2 = u1.copy(name = "Randy")
    println("u1: name = ${u1.name}, name = ${u1.age")
    println("u2: name = ${u2.name}, name = ${u2.age")
}

このプログラムを実行すると、出力は以下のようになります:

u1: name = John, name = 29
u2: name = Randy, name = 29

toString()方法 - 返回字符串

toString()函数返回该对象的字符串表示形式。

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val u1 = User("ジョン", 29)
    println(u1.toString())
}

このプログラムを実行すると、出力は以下のようになります:

User(name=John, age=29)

hashCode() 和 equals()

hashCode() 方法返回对象的散列码。 如果两个对象相等,则hashCode()会产生相同的整数结果。

如果两个对象相等(hashCode()相同),则equals()返回true。如果对象不相等,equals()返回false。

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val u1 = User("ジョン", 29)
    val u2 = u1.copy()
    val u3 = u1.copy(name = "Amanda")
    println("u1 hashcode = ${u1.hashCode()")
    println("u2 hashcode = ${u2.hashCode()")
    println("u3 hashcode = ${u3.hashCode()")
    if (u1.equals(u2) == true)
        println("u1 等于 u2.")
    else
        println("u1 不等于 u2.")
    if (u1.equals(u3) == true)
        println("u1 等于 u3.")
    else
        println("u1 不等于 u3.")
}

このプログラムを実行すると、出力は以下のようになります:

u1 hashcode = 71750738
u2 hashcode = 71750738
u3 hashcode = 771732263
u1 等于 u2.
u1 不等于 u3.

解构声明

您可以使用解构声明将一个对象分解为多个变量。例如:

data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
    val u1 = User("ジョン", 29, "男性")
    val (name, age, gender) = u1
    println("name = $name")
    println("age = $age")
    println("gender = $gender")
}

このプログラムを実行すると、出力は以下のようになります:

name = ジョン
age = 29
gender = 男性

これはコンパイラがデータクラスの component() 関数のすべての属性を生成するためによくあることです。 例えば:

data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
    val u1 = User("ジョン", 29, "男性")
    println(u1.component1())     // ジョン
    println(u1.component2())     // 29  
    println(u1.component3())     // "男性"
}

このプログラムを実行すると、出力は以下のようになります:

ジョン
29
男性