Effective Kotlin: Item 10 — Obey the general contract when overriding equals

With item 10 of Effective Java, Joshua Bloch goes into great detail of how to write an excellent equals method and doing the same in Kotlin is no exception.

The data class is one of Kotlin’s most touted features as they already implement equals for you. However, one thing to be aware of is that as of Kotlin 1.2 the order in which Kotlin compares properties of a data class follows the order of declaration. Therefore the code below will first compare the name and then the age:

data class User(val name: String, val age: Int)

Joshua suggests that “for best performance, you should first compare fields that are more likely to differ, less expensive to compare, or, ideally, both.” In our example we can achieve this by just changing the order to check the primitive type first:

data class User(val age: Int, val name: String)

Of course, changing the order in your classes may not always make sense, Kotlin does, of course, give you named parameters that will help.

One of the hardest problems to solve with equals is with sub-types where following the Liskov substitution principle “any important property of a type should also hold for all its subtypes so that any method written for the type should work equally well on its subtypes”. Interestingly you cannot extend a data class because “there is no way to make compiler-generated data class methods work consistently and intuitively in case of inheritance.”

Each week I am looking at “items” from Joshua Bloch’s well-respected book, Effective Java to see how it applies to Kotlin. You can find the rest of the items I’ve covered at Effective Kotlin. Please let me know your thoughts.

Matt Dolan has been eating doughnuts and developing with Android since the dark days of v1.6.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store