As I’m learning Kotlin, I’m trying to implement a simple Tree.
The problem is my equals implementation is buggy, and i can’t figure out why
I have a node class with autogenerated by intellij equals
class Node(val value: String) {
var parent: Node? = null
val children = mutableSetOf<Node>()
var depth: Int = 0
fun addChild(child: Node) {
children.add(child)
child.parent = this
child.depth = depth + 1
}
override fun toString(): String {
return "$value-$depth" + (children.map { it.toString() })
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Node
if (value != other.value) return false
if (children != other.children) return false // why is this false?
if (depth != other.depth) return false
return true
}
override fun hashCode(): Int {
var result = value.hashCode()
result = 31 * result + children.hashCode()
result = 31 * result + depth
return result
}
}
And a very simple Junit test
@Test
fun `Equals Implementation Ignores Child Order`() {
val root = Node("COM")
val b = Node("B"); root.addChild(b)
val g = Node("G"); b.addChild(g)
val h = Node("H"); g.addChild(h)
val root1 = Node("COM")
val b1 = Node("B"); root1.addChild(b1)
val g1 = Node("G"); b1.addChild(g1)
val h1 = Node("H"); g1.addChild(h1)
assertEquals(root, root1)
}
During debugging, the equals fails at the line if (children != other.children) return false
, but I cannot figure out why.
Checking equality of mutableSetOf(Node("a"))==mutableSetOf(Node("a"))
returns true, as expected, and if i remove the children check inside equals, the jUnit also returns true. (I cannot remove that equals though as 2 trees must have equal children to be equal)
A second question is: Why is equals
not called recursively for each child? This is what i would expect, but it doesn’t happen.