# When implementing Comparable overriding equals and hashcode is must?

Whenever I implement Comparable Interface then should I have to override equals() and hashcode().

Let Suppose, I have to use Priority Queue and I have custom class. So to use Priority Queue I have to implement Comparable. But my confussion is It might have two different order and it basically depends on Priority Queue’s Implementation.

CASE 1 → If Priority Queue internally uses == to compare
CASE 2 → If Priority Queue internally uses compareTo to compare

CASE 1 and CASE 2 will return different order

``````class TestNode(val vertex : Int, var weight : Int = Int.MAX_VALUE) : Comparable<TestNode> {

override fun hashCode(): Int {
return vertex
}

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

other as TestNode

if (vertex != other.vertex) return false

return true
}

override fun compareTo(other: TestNode): Int = when {
this.weight < other.weight -> -1
this.weight > other.weight -> 1
else -> 0
}
}

fun isEqual(a : TestNode, b : TestNode) = (a == b)
fun isEqualByCompare(a : TestNode, b : TestNode) = a.compareTo(b) == 0

fun main() {
val a = TestNode(1, 34)
val b = TestNode(9, 34)
println("\${isEqual(a,b)}")
println("\${isEqualByCompare(a,b)}")
}
``````

I checked Priority Queue’s implementation and got the information that its uses compareTo. But what about other peoples code. They might use == or compareTo.

Am I missing something very basic? Can someone give some insight?

1 Like

Why do you think `PriorityQueue` ever uses `equals()`? Its documentation clearly states it uses comparators. Also, I don’t see how `equals()` could be used for sorting. It only provides info about equality, but it doesn’t say which item is smaller/bigger.

1 Like

I don’t think Kotlin should enforce overriding equals() and hashCode(), since there are cases where failing to do so is entirely justifiable.

The docs for `java.util.Comparable` explicitly allow for orderings that are not ‘consistent with equals’.

They say that consistency with equals (where `a.compareTo(b) == 0` has the same value as `a.equals(b)` for every `a` and `b` of that class) is ‘strongly recommended’, and that e.g. sorted sets and sorted maps are likely to have problems with keys which have a natural ordering inconsistent with equals.

But they give one case where lack of consistency with equals makes sense: `BigDecimal`. The BigDecimal values “1” and “1.0” are not equal, because they have different precisions; however, neither is larger or smaller than the other, and so `compareTo()` should return 0.

(Of course, the situation for `kotlin.Comparable` is identical, though its docs don’t mention any of this. It’s one of many cases where the Kotlin docs fall far short of the very high standard of the Java docs, and it’s well worth checking out the latter where appropriate.)

If a class has a natural ordering which is not consistent with equals, then that should be documented very clearly, to avoid nasty surprises. And similarly, classes which require an ordering consistent with equals should document that too. (Classes in the standard library such as `SortedSet` do indeed make that very clear.)

But no, I don’t think Kotlin should enforce overriding equals() and hashCode().

An IDE inspection could be a good idea, though, to ensure that failing to do is a deliberate decision and not just an oversight.

2 Likes