Trong bài này, bạn sẽ học cách tạo các data class trong Kotlin. Bạn cũng sẽ tìm hiểu về các yêu cầu mà data class phải đáp ứng và các chức năng tiêu chuẩn của chúng.

Sẽ có nhiều trường hợp mà bạn cần tạo một class chỉ để lưu trữ giữ dữ liệu. Trong những trường hợp như vậy, bạn có thể đánh dấu class là data để tạo data class. Ví dụ,

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

Đối với class này, trình biên dịch tự động tạo:

  • Hàm copy(), cặp equals()và hashCode(), và dạng toString() của hàm tạo chính
  • Hàm componentN() 

Trước khi nói chi tiết về các tính năng này, hãy tìm hiểu về các yêu cầu mà một data class phải đáp ứng.

1. Yêu cầu cho data class trong Kotlin

Dưới đây là các yêu cầu:

  • Hàm tạo chính phải có ít nhất một tham số.
  • Các tham số của hàm tạo chính phải được đánh dấu là val (chỉ đọc) hoặc var (đọc-ghi).
  • Class không được mở, trừu tượng, không được phép là class bên trong hoặc sealed class.
  • Class có thể mở rộng các class khác hoặc triển khai các interface. Nếu bạn đang sử dụng phiên bản Kotlin trước 1.1, class chỉ có thể triển khai các interface.

2. Ví dụ: data class trong Kotlin

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

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}")
}

Khi bạn chạy chương trình, kết quả sẽ là:

name = jack
age = 29

Khi bạn khai báo một data class, trình biên dịch sẽ tự động tạo một số chức năng như toString(), equals(), hashcode()vv đằng sau hậu trường. Điều này giúp giữ cho bạn mã ngắn gọn. Nếu bạn đã sử dụng Java, bạn sẽ cần viết rất nhiều mã soạn sẵn.

Hãy sử dụng các chức năng sau:

3. Sao chép

Đối với một data class, bạn có thể tạo một bản sao của một đối tượng với một số thuộc tính khác nhau của nó bằng hàm copy(). Sau đây là cách nó hoạt động:

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}")
}

Khi bạn chạy chương trình, kết quả sẽ là:

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

Hàm toString ()

Hàm toString() trả về một biểu diễn dưới dạng chuỗi của đối tượng.

data class User(val name: String, val age: Int)

fun main(args: Array<String>) {
    val u1 = User("John", 29)
    println(u1.toString())
}

Khi bạn chạy chương trình, kết quả sẽ là:

User(name=John, age=29)

4. hashCode () và equal()

Hàm hashCode() trả về hash code của đối tượng. Nếu hai đối tượng bằng nhau,  hashCode() tạo ra cùng một kết quả số nguyên. Bạn hãy đọc bài viết: hashCode()

equals() trả về true nếu hai đối tượng bằng nhau (có cùng hashCode()). Nếu các đối tượng không bằng nhau, equals()trả về false. Bạn hãy đọc bài viết: equals()

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

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.")
}

Khi bạn chạy chương trình, kết quả sẽ là:

u1 hashcode = 71750738
u2 hashcode = 71750738
u3 hashcode = 771732263
u1 is equal to u2.
u1 is not equal to u3.

5. Khai báo hàm hủy

Bạn có thể hủy cấu trúc một đối tượng và biến nó thành một số biến bằng cách sử dụng khai báo hủy . Ví dụ:

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")
}

Khi bạn chạy chương trình, kết quả sẽ là:

name = John
age = 29
gender = Male

Chúng ta có thể làm được điều này vì trình biên dịch tạo ra các hàm componentN() triển khai tất cả các thuộc tính cho một data class. Ví dụ:

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"
}

Khi bạn chạy chương trình, kết quả sẽ là:

John
29
Male

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!