Data class in Kotlin : Explanation with example

Data class in Kotlin is used mainly for classes that holds only data. Keyword ‘data’ is used to mark a class data class. These classes cann’t be used to define any extra functionalities to a class. By default, this class will provide you few methods. In this tutorial, we will learn about data class in Kotlin , its benifit and use cases.

How to create a data class :

Data class was mainly used to remove boilerplate code that we write in Java programs. Suppose , you want to create one class that stores the data of a student : name , age and rank. In Java, we can write one Student class as like below :

class Student {
    private String name;
    private int age;
    private int rank;

    public Student(String name, int age, int rank) {
        this.name = name;
        this.age = age;
        this.rank = rank;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }
}

This class holds one constructor and getter/setter only for three elements. So, how big this class will become if you have 10 or 20 elements !! Again, if you want to add few more methods like equals(), hashCode(), toString() etc., the size will increase more and ofcourse the development time to write all of these code.

Kotlin makes all of these thing easier for us. So, to create a class that holds all getter/setter and other methods , we need only one line of code :

data class Student(val name: String, val age: Int, val rank: Int)

Remember that :

  1. The primary constructor of the class should not be empty. It should contain atleast one parameter.
  2. All of these parameters should be either val or var.
  3. data classes cannot be inner, sealed, open or abstract.
  4. They may extend other classes and implement interfaces .Extend other class is available starting Kotlin 1.1.

This class will automatically derive the following methods :

  1. getter/setter
  2. equals(), hashCode()
  3. copy()
  4. componentN() functions

The compiler will automatically generate these functions. Let me show you with one example :

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

fun main(args: Array) {
    val albert = Student("Albert", 21,3)
    println("name = ${albert.name}")
    println("current rank : ${albert.rank}")

    //set different rank
    albert.rank = 2
    println("current rank : ${albert.rank}")
}

Output :

name = Albert
current rank : 3
current rank : 2

kotlin data class

Awesome, isn’t it ?

Declare properties in the class body :

In the above example, we have created one data class with three parameters in the constructor. If we want, we can have only one property in the constructor and declare other two inside the class.

data class Student(val name: String){
    val age: Int = 10 
    var rank: Int = 0
}

fun main(args: Array) {
    val albert = Student("Albert")
    albert.rank = 3

    println("name = ${albert.name}")
    println("rank : ${albert.rank}")

    val albert2 = Student("Albert")
    albert2.rank = 1 
    
    println("name = ${albert2.name}")
    println("rank : ${albert2.rank}")
}

It will print the output below :

name = Albert
rank : 3
name = Albert
rank : 1

This looks exactly same as the above example, but the main problem is that only the parameter that is defined in the constructor, i.e. name here , is used to implement the methods toString(),equals(), hashCode() and copy(). And there will be only one component function component1(). So, if we compare the above objects using equals(), they will be treated as equal, even though the value of rank is different for both of them.

Using default and named arguments in data class :

We can even use default and named arguments in a data class and that makes lot more useful. Let me show you how. Change the above class as below :

data class Student(val name: String = "Albert", val age: Int = 19, var rank: Int = 3)

Now, we can use this class like below :

val student = Student("Alex", 21)

val student1 = Student()

val student2 = Student(rank=4)

The first statement will create one Statement with name as Alex and age 21, second statement will assign all the default values and the third one will assign rank as 4. Full example :

data class Student(val name: String = "Albert", val age: Int = 19, var rank: Int = 3)

fun main(args: Array) {
    val student = Student("Alex", 21)
    println("name = ${student.name}")
    println("age = ${student.age}")
    println("current rank : ${student.rank}")

    val student1 = Student()
    println("name = ${student1.name}")
    println("age = ${student1.age}")
    println("current rank : ${student1.rank}")

    val student2 = Student(rank=4)
    println("name = ${student2.name}")
    println("age = ${student2.age}")
    println("current rank : ${student2.rank}")

}

Output :

name = Alex
age = 21
current rank : 3
name = Albert
age = 19
current rank : 3
name = Albert
age = 19
current rank : 4

Copy object using copy() :

We can copy an object easily with the copy() method. During copy , we can even change its properties. Example :

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

fun main(args: Array) {
    val student1 = Student("Alex", 21, 2)
    println("student1 name : ${student1.name} , age : ${student1.age} , rank : ${student1.rank}")

    val student2 = student1.copy(name = "Albert",rank = 3)
    println("student2 name : ${student2.name} , age : ${student2.age} , rank : ${student2.rank}")

}

Output :

student1 name : Alex , age : 21 , rank : 2
student2 name : Albert , age : 21 , rank : 3

kotlin data class

String value using toString() :

toString() method returns the string value of a data class object in kotlin. Example :

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

fun main(args: Array) {
    val student1 = Student("Alex", 21, 2)
    println(student1.toString())
}

It will print :

Student(name=Alex, age=21, rank=2)

equals() and hashCode() methods :

equals() and hashCode() methods are equally helpful as other previous methods. hashCode() method generates one integer value for an object. If two objects are equal, both will have same hashCode value. equals() method checks if two objects are equal or not. It returns true or false. Example :

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

fun main(args: Array) {
    val student1 = Student("Alex", 21, 2)
    val student2 = Student("Alex", 21, 2)
    val student3 = Student("Albert", 21, 2)

    println("HashCode for student1 : ${student1.hashCode()}")
    println("HashCode for student2 : ${student2.hashCode()}")
    println("HashCode for student3 : ${student3.hashCode()}")

    if(student1.equals(student2)){
        println("student1 and student2 are equal")
    }

    if(!student1.equals(student3)){
        println("student1 and student3 are not equal")
    }

}

Output :

HashCode for student1 : 1963759947
HashCode for student2 : 1963759947
HashCode for student3 : 1582112541
student1 and student2 are equal
student1 and student3 are not equal

kotlin data class

Conclusion :

In this post, we have covered almost all different types of use cases for data class in kotlin. You can refer the official doc to learn more. Try to run the examples above and drop one comment below if you have any queries.

You might also like :