I am trying to build "by hand" a linked list and I keep getting the exception.
Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.example.interview.Node.toString()
I do not want to use the pre-build linked list from kotlin. This is an exercise, so I need to build everything by hand. Why I have to override the toString()? Even when I do, it crashes the same way.
Code:
data class Node(
var value: Int,
var next: Node? = null,
var prev: Node? = null
) {
}
fun makeLinkedList() {
val root = Node(1)
val node1 = Node(2)
val node2 = Node(3)
val node3 = Node(4)
root.next = node1
node1.prev = root
node1.next = node2
node2.prev = node1
node2.next = node3
node3.prev = node2
var it = root
do {
println(it.toString())
it = it.next!!
} while (it != null)
}
I look into this thread, but it is not even Kotlin. Did not help much:
Spring JPA bi-directional cannot evaluate toString
CodePudding user response:
data class
automatically provides toString()
implementation which prints all properties. Such implementation isn't very useful in this specific case as doubly linked lists naturally contain circular references between nodes, so toString()
iterates over nodes in circles, indefinitely. To print the first node it tries to print the second one, but to print the second one it tries to print the first one. And so on. You will have the same problem with other functions generated by the data class: hashCode()
and equals()
.
I believe in this case you don't benefit from data classes in any way, so you should define Node
as a regular class. Alternatively, you can remove prev
from a list of properties that data class
handles in a special way:
data class Node(
var value: Int,
var next: Node? = null,
) {
var prev: Node? = null
}
This way toString()
will still provide ugly result, so you could override it, but at least hashCode()
and equals()
should properly compare the whole list.
Also, by looking how you print each node to see the whole list (and not only the head), it seems you didn't really plan for Node
to represent a whole list, but only this single node. In this case you could prefer to remove next
from data properties as well or again, do not use data class
at all.