Reputation: 1067
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 &&
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()
?
Upvotes: 2
Views: 4508
Reputation: 2129
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
Upvotes: 1
Reputation: 31234
A solution that has worked well for me is to separate your metadata from your data. e.g.:
data class Entity<out T>(val id: Int, val data: T)
data class Person(val name: String, val manufacturer: String)
Usage:
val e1 = Entity(1, Person("Mickey", "Disney"))
val e2 = Entity(2, Person("Mickey", "Disney"))
val e3 = Entity(3, Person("Donald", "Disney"))
e1 == e2
// false
e1.data == e2.data
// true
e2.data == e3.data
// false
Upvotes: 2
Reputation: 89578
For data classes, these functions are generated using all the properties that are declared in the primary constructor. From the official documentation:
The compiler automatically derives the following members from all properties declared in the primary constructor:
- equals()/hashCode() pair,
- toString() of the form "User(name=John, age=42)",
- componentN() functions corresponding to the properties in their order of declaration,
- copy() function (see below).
If you want a property not to be taken into account for their implementation, you'll have to either move it out of the primary constructor, or implement these functions yourself.
More discussion about a similar issue here.
Upvotes: 5