Compare data class in Kotlin without ID

2019-09-18 16:01发布

问题:

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.



标签: kotlin