I have a data class in Kotlin, which has number of properties, one of which is ID
. But when I actually use compare
function in code, I would like to exclude this ID
property when comparing. Is there any way to do that except manually boilerplating compare
function?
问题:
回答1:
You can use the copy()
function on one of your data class instances to create a copy of it "altering some of its properties". e.g.:
data class User(val id: Long, val name: String)
val a = User(1, "John")
val b = User(2, "John")
println(a == b) // false
println(a.copy(id = b.id) == b) // true
Creating a copy of one of your data class instances and altering the id to be the same as the other instance you want to compare against allows to effectively ignore that property.
You could also copy both data class instances and set id
to some common value but if you are only doing one-off comparisons then this would be an unnecessary call to copy()
.
回答2:
A data class generates the equals
function (compare
is not generated) based on the properties that are declared in the primary constructor, so if you want it not to compare the IDs, you'll have to move the ID
property out of the primary constructor.
The obvious part is that you have to move the property to the body of the class, but then you'll also have to make it a var
since it won't be initialized in the primary constructor (you can't have it be a val
and initialize it to a default value in the init
block, because then you can't assign to it in the secondary constructor).
An example of how you can do this:
data class User(val id: Long, val name: String)
data class ModifiedUser(val name: String) {
var id: Long = 0
constructor(id: Long, name: String) : this(name) {
this.id = id
}
}
val u1 = User(1, "John")
val u2 = User(2, "John")
println(u1 == u2) // false
val m1 = ModifiedUser(1, "Sally")
val m2 = ModifiedUser(2, "Sally")
println(m1 == m2) // true
It's up to you to decide which way suits you better, but maybe it's easiest to just override equals
(and by implication, hashCode
) to get the desired result, at least it contains the code related to this in just once place, while the above solution can complicate your class quite a bit.