有时,您可能需要创建一个仅用于保存数据的类。在这种情况下,您可以将类标记为 data
来创建一个数据类。例如,
data class Person(val name: String, var age: Int)
对于这个类,编译器会自动生成
copy()
函数,equals()
和hashCode()
对,以及主构造函数的toString()
形式componentN()
函数
在详细介绍这些特性之前,我们先来谈谈数据类必须满足的要求。
Kotlin 数据类要求
以下是要求:
- 主构造函数必须至少有一个参数。
- 主构造函数的参数必须标记为
val
(只读)或var
(读写)。 - 类不能是 open、abstract、inner 或 sealed。
- 类可以继承其他类或实现接口。如果您使用的是 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()
函数创建一个具有某些不同属性的对象副本。它的工作原理如下:
data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
val u1 = User("John", 29)
// using copy function to create an object
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("John", 29)
println(u1.toString())
}
运行程序后,输出将是
User(name=John, age=29)
hashCode() 和 equals()
hasCode()
方法返回对象的哈希码。如果两个对象相等,hashCode()
会产生相同的整数结果。推荐阅读: hashCode()
equals()
返回 true
,如果两个对象相等(具有相同的 hashCode()
)。如果对象不相等,equals()
返回 false
。推荐阅读: equals()
data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
val u1 = User("John", 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 is equal to u2.")
else
println("u1 is not equal to u2.")
if (u1.equals(u3) == true)
println("u1 is equal to u3.")
else
println("u1 is not equal to u3.")
}
运行程序后,输出将是
u1 hashcode = 71750738 u2 hashcode = 71750738 u3 hashcode = 771732263 u1 is equal to u2. u1 is not equal to u3.
解构声明
您可以使用 解构声明 将对象解构为多个变量。例如,
data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
val u1 = User("John", 29, "Male")
val (name, age, gender) = u1
println("name = $name")
println("age = $age")
println("gender = $gender")
}
运行程序后,输出将是
name = John age = 29 gender = Male
之所以可能,是因为编译器为数据类的所有属性生成了 componentN()
函数。例如,
data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
val u1 = User("John", 29, "Male")
println(u1.component1()) // John
println(u1.component2()) // 29
println(u1.component3()) // "Male"
}
运行程序后,输出将是
John 29 Male