DataClass

如何写一个简单的数据存储类?

除了存储信息,类还应该能够比较对象、复制对象,并且方便地输出数据。通常,为了实现这些功能,类需要定义以下几个方法:

  • equals()hashCode() —— 用于对象比较和在集合中正确工作。

  • copy() —— 用于复制对象,创建一个带有部分修改的新对象。

  • toString() —— 用于打印对象的字符串表示,方便调试。

  • componentN() 函数 —— 用于解构声明,按属性声明顺序一一对应。

但是在 Kotlin 中,你不需要自己写这些方法,只要用 data class 关键字就可以自动帮你实现。


Data class 示例

我们先定义一个普通类:

class Client(val name: String, val age: Int, val gender: String)

这个类有 3 个属性。为了比较两个对象是否相等(根据属性值),你通常需要重写 equals()hashCode() 方法:

class Client(val name: String, val age: Int, val gender: String) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as Client

        if (name != other.name) return false
        if (age != other.age) return false
        if (gender != other.gender) return false

        return true
    }

    override fun hashCode(): Int {
        var result = name.hashCode()
        result = 31 * result + age
        result = 31 * result + gender.hashCode()
        return result
    }
}

这段代码很长,而且都是“标准模板”,非常重复且容易出错。


用 data class 简化

有了 data 关键字,Kotlin 会自动帮你生成这些代码:

data class Client(val name: String, val age: Int, val gender: String)

这样就足够了,equals()hashCode()toString()copy()componentN() 都自动生成。


注意事项

  1. 只有主构造函数中的属性会参与自动生成的函数
data class Client(val name: String, val age: Int, val gender: String) {
    var balance: Int = 0
}

这里 balance 不在主构造函数中,所以不会参与 equals()hashCode() 等函数。

  1. 可以覆盖自动生成的方法,但不能覆盖 copy() 方法
data class Client(val name: String, val age: Int, val gender: String) {
    var balance: Int = 0

    override fun toString(): String {
        return "Client(name='$name', age=$age, gender='$gender', balance=$balance)"
    }
}

这样 toString() 里也会显示 balance 字段。

  1. 主构造函数必须至少有一个参数,且所有参数必须是 valvar

copy() 和 componentN() 函数

Kotlin 中复制对象很方便:

fun main() {
    val bob = Client("Bob", 29, "Male")
    val john = bob.copy(name = "John")
    println(bob)
    println(john)
}

输出:

Client(name=Bob, age=29, gender=Male)
Client(name=John, age=29, gender=Male)

这时,johnbob 的副本,只改了名字。

componentN() 函数允许你按顺序访问属性:

fun main() {
    val bob = Client("Bob", 29, "Male")
    println(bob.component1()) // Bob
    println(bob.component2()) // 29
    println(bob.component3()) // Male

    // 解构声明
    val (name, age, gender) = bob
    println(name) // Bob
    println(age)  // 29
    println(gender) // Male
}

小结

  • data class 是 Kotlin 用来简化存储数据的类的一个非常方便的关键字。

  • 自动帮你生成比较、复制、打印和解构相关的函数,极大减少模板代码。

  • 适合用于数据传输对象(DTO)和简单的值对象。

  • 只要记住主构造函数里声明的属性才参与自动生成的逻辑。

  • 用得好可以省时省力,让代码更简洁。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值