How to implement `equals` and `hashCode` on `List` subtypes?


#1

I just noticed that, in contrast to what is done in Java, the List interface in Kotlin does not define either equals or hashCode methods.

This is also true for other interfaces like Set and Map.

From what I understand, this means that the following statements are not necessarily true (although they actually are in practice):

  • listOf(1) == arrayListOf(1)
  • listOf(1).hashCode == arrayListOf(1).hashCode

So, this leads to the following questions:

  • Why doesn’t the List interface in Kotlin explicitly override equals and hashCode (as its counterpart in Java does)?
  • Say I want to create a custom List implementation called MyEmptyList. Instances from this class are always empty. This means that MyEmptyList() == emptyList() should be always true. How should hashCode be implemented in this case?

#2

As far as I know Javas List interface does not override hashCode or equals. The interface declares that each list needs to implement hashCode and equals. The jdoc documentation just states how this should be implemented.
This should also answer your second question.
Kotlins Lists do not have equals and hashCode as part of the interface description because all classes in Kotlin are a subclass of Any which declares hashCode and equals already.

If you look at the code of ArrayList for example you see that it extends AbstractList which implements hashCode. There is also an equivalent class called AbstractSequentialList which should be used for lists backed by sequentially accessed data.