Introduction

Over the last few weeks I have been playing around with Kotlin.

First let me tell you that it can be a bit frustrating because Kotlin is far from a finished product. It works on an EAP version of IntelliJ with nightly builds of the plugin. So you are bound to have version that don’t work. I had 2 of those over the last week. But it now works with IntelliJ 123.4 and kotlin plugin 0.4.214.

And that things still change can be proven by the fact that the samples use tuples while tuples have been removed and replaced by data classes. So you can expect to find errors in the documentation and in the samples on github.

But we are here to learn. And I found the concept of the data class very intriguing.

The class

in kotlin you can define a class like this.

Java
1
class MyClass(val i : Int, val s : String)
class MyClass(val i : Int, val s : String)

That’s a class with two properties named i and s.

And we can read out all the usual methods like this.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun main(args : Array<String>) {
    val c1 = MyClass(1,"t")
    val c2 = MyClass(1,"t")
    val c3 = MyClass(2,"t")
    println(c1.toString())
    println(c1.equals(c2))
    println(c1.equals(c3))
    println(c1.equals(c1))
    println(c1.hashCode())
    println(c2.hashCode())
    println(c3.hashCode())
    println(c1.i)
    println(c1.s)
}
fun main(args : Array<String>) {
    val c1 = MyClass(1,"t")
    val c2 = MyClass(1,"t")
    val c3 = MyClass(2,"t")
    println(c1.toString())
    println(c1.equals(c2))
    println(c1.equals(c3))
    println(c1.equals(c1))
    println(c1.hashCode())
    println(c2.hashCode())
    println(c3.hashCode())
    println(c1.i)
    println(c1.s)
}

with this as the result.

demo.MyClass@337d0f
false
false
true
3374351
21356612
8831815
1
t

That’s how I would expect any class to behave even in .Net and Java. Nothing special.

The data class

Now lets add the keyword data in front of it.

Java
1
data class MyClass(val i : Int, val s : String)
data class MyClass(val i : Int, val s : String)

and run our code again.

MyClass(i=1, s=t)
true
false
true
147
147
178
1
t

the result is completely different. c1 and c2 are the same the tostring is differnt and the hashcodes are different.

The data class behaves as a DTO.

But the data class is also a tupple.

Which we can demonstrate by adding these two lines to our main.

Java
1
2
println(c1.component1())
    println(c1.component2())
println(c1.component1())
    println(c1.component2())

Which will now give us the following output.

MyClass(i=1, s=t)
true
false
true
147
147
178
1
t
1
t

Just like a tupple.

So tostring, equals and hashcode are autoimplemented for a data class and based on the properties you provide.

But you can also override that behavior if you want.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data class MyClass(val i : Int, val s : String)
{
    fun equals(val obj : Any) : Boolean {
        return (obj as MyClass).s.equals(s)
    }
 
    fun hashCode() : Int
    {
        return s.hashCode()
    }
 
    fun toString() : String {
        return s.toString()
    }
}
data class MyClass(val i : Int, val s : String)
{
    fun equals(val obj : Any) : Boolean {
        return (obj as MyClass).s.equals(s)
    }

    fun hashCode() : Int
    {
        return s.hashCode()
    }

    fun toString() : String {
        return s.toString()
    }
}

with this as the result.

t
true
true
true
116
116
116
1
t
1
t

Cool.

Conclusion

I very much like the data class and it would come in handy in many other languages.