Ignoring certain properties when generating equals(), hashCode(), etc

Let’s say I have a data class that has three properties:

data class Product(
    val id: Int,
    val name: String,
    val manufacturer: String)

If I understand correctly, Kotlin will generate equals() and hashCode() using all the three properties, which will be like:

override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other == null || javaClass != other.javaClass) return false
    val that = other as Product?
    return id == that.id && // Possible to not use "id"?
            name == that!!.name &&
            manufacturer == that.manufacturer
}

override fun hashCode(): Int {
    return Objects.hash(id, name, manufacturer)
}

So what if I don’t want id to be used in equals() and hashCode()? Is there a way to tell Kotlin to ignore certain properties when generating these functions? How about toString() and compareTo()?

3 Likes

No. If you need non-standard generation of any data class methods, you can override them and provide any implementation you need.

1 Like

From the documentation:

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.

Your example has to look like this:

data class Product(
    val name: String,
    val manufacturer: String) {
    val id: Int
}

For more information take a look at: https://kotlinlang.org/docs/reference/data-classes.html#properties-declared-in-the-class-body

11 Likes

Not possible, the id should be defined as abstract or initialized, so your answer is wrong I am afraid.

I believe you can do this:

data class Product private constructor(
    val name: String,
    val manufacturer: String) {
    private var _id: Int = 0
    val id get() = _id
    constructor(name: String, manufacturer: String, id: Int): this(name, manufacturer) {
        _id = id
    }
}

fun main() {
    val product1 = Product("hello", "world", 1)
    val product2 = Product("hello", "world", 2)
    println(product1 == product2)
}