More compact equals?

Now android studio generates method equals as below:

class Current(val id: Long) {
    
       override fun equals(other: Any?): Boolean {
               if (this === other) return true
               if (javaClass != other?.javaClass) return false

               other as Current

              if (id != other.id) return false

             return true
     }
}

I often rewrite it to:

class Compact(val id: Long) {

      override fun equals(other: Any?): Boolean {
             return other is Compact && id == other.id
      } 
}

Does my variant has some whitespaces? Is current variant generated by ide too verbose?

1 Like

I think you don’t even need that if you call it from kotlin.

That auto generated equals looks like a relic from Java.
In my experience often you can make classes that require equals data classes.

It is required to handle null and smart cast.

Data classes are forbidden in my projects for android because of too much clutter generation and dramatically method count increase which pushes application over 64k limit which removes some speed benefits when app fits in this limit.

1 Like

The generated equals is verbose, yes. But still, there’s some important things to notice:

  • if (this === other) return true → short-circuit/fast path for faster detection on same object instance
  • (javaClass == other?.javaClass) is not the same test as other is Compact. In the first case, inherited classes are forbidden (preserve simmetry), and in your rewritten case, they are (broken symmetry). there’s plenty of article discussing this difference, like this one.

I think that preserving symmetry or not depends on your use cases, but I may be wrong. Kotlin makes this problem “disappear” for data classes by simply preventing them to inherit each other (but of course, inheriting from standard classes is Ok, because the responsability of the equal method in parent class is transfered to the developper).

3 Likes

This would lead to infinite recursion as kotlins a == b is translated to a.equals(b). I think you meant to use this === other which tests for reference equality and not data equality.

1 Like

Yes, you’re right :slight_smile: . Coming from Java world, I’m still not used to operator overload. I’ve fixed my answer.

1 Like

yes. I usually rewrite it to
equals(other:Any?) = (other as? Compact)?.id==id