Kotlin equals and hash code generator

You can't do something like this for data classes, they always generate equals and hashCode the same way, there's no way to provide them such hints or options.

However, they only include properties that are in the primary constructor, so you could do this for them to only include index:

data class CSVColumn(private val index: Int, value: String) {
    val value: String = value
}

... except you can't have parameters in the primary constructor that aren't properties when you're using data classes.

So you'd have to somehow introduce a secondary constructor that takes two parameters, like this:

class CSVColumn private constructor(private val index: Int) {

    var value: String = ""

    constructor(index: Int, value: String) : this(index) {
        this.value = value
    }

}

... but now your value property has to be a var for the secondary constructor to be able to set its value.

All this to say that it's probably not worth trying to work around it. If you need an non-default implementation for equals and hashCode, data classes can't help you, and you'll need to implement and maintain them manually.


Edit: as @tynn pointed out, a private setter could be a solution so that your value isn't mutable from outside the class:

class CSVColumn private constructor(private val index: Int) {

    var value: String = ""
        private set

    constructor(index: Int, value: String) : this(index) {
        this.value = value
    }

}

From the Data Classes documentation you get:

Note that the compiler only uses the properties defined inside the primary constructor for the automatically generated functions. To exclude a property from the generated implementations, declare it inside the class body

So you have to implement equals() and hashCode() manually or with the help of a Kotlin Compiler Plugin.


I wrote a little utility called "stem", which allows you to select which properties to consider for equality and hashing. The resulting code is as small as it can get with manual equals()/hashCode() implementation:

class CSVColumn(private val index: Int, val value: String)  {
    private val stem = Stem(this, { index })

    override fun equals(other: Any?) = stem.eq(other)
    override fun hashCode() = stem.hc()
}

You can see its implementation here.

Tags:

Kotlin