在 Kotlin 中使链表"by hand"不断从方法中抛出异常"toString"



我正在尝试构建"手工";一个链接列表,我不断得到例外。

Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.example.interview.Node.toString()

我不想使用kotlin的预构建链接列表。这是一个练习,所以我需要手工制作所有的东西。为什么我必须重写toString((?即使我这样做,它也会以同样的方式崩溃。

代码:

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)
}

我看了看这根线,但它甚至不是Kotlin。帮助不大:

Spring JPA双向无法评估toString

data class自动提供打印所有属性的toString()实现。在这种特定情况下,这样的实现不是很有用,因为双链表自然包含节点之间的循环引用,所以toString()无限期地在循环中的节点上迭代。要打印第一个节点,它将尝试打印第二个节点,但要打印第二节点,它会尝试打印第一个。等等。数据类生成的其他函数hashCode()equals()也会遇到同样的问题。

我相信在这种情况下,您无论如何都不会从数据类中受益,所以您应该将Node定义为一个常规类。或者,您可以从data class以特殊方式处理的属性列表中删除prev

data class Node(
var value: Int,
var next: Node? = null,
) {
var prev: Node? = null
}

这样toString()仍然会提供难看的结果,所以您可以覆盖它,但至少hashCode()equals()应该正确地比较整个列表。

此外,通过查看如何打印每个节点以查看整个列表(而不仅仅是头部(,您似乎并没有真正计划让Node表示整个列表,而是只表示这一个节点。在这种情况下,您可能更喜欢从数据属性中删除next,或者再次,完全不要使用data class

最新更新