手动实现Kotlin双向链表时toString方法抛出StackOverflowError异常
双向链表toString抛出StackOverflowError的原因及解决方法
问题根源
你的Node类是Kotlin的data class,Kotlin会自动为data class生成toString()方法,该方法会递归打印所有属性值。由于双向链表的节点存在循环引用(比如root.next = node1同时node1.prev = root),调用toString()时会无限递归遍历next和prev引用,最终导致StackOverflowError。
即便你尝试重写toString(),如果重写的方法仍然包含对next或prev的完整节点引用(比如直接打印next对象),依然会触发循环递归,导致同样的异常。
另外你的遍历代码存在潜在NPE风险:do-while循环中,当遍历到最后一个节点(node3)时,it.next为null,执行it = it.next!!会直接抛出NullPointerException。
解决方法
1. 正确重写toString()方法
重写时避免直接引用会导致循环的next或prev节点,只打印必要信息(比如仅打印节点值,或仅打印关联节点的数值而非完整对象):
data class Node( var value: Int, var next: Node? = null, var prev: Node? = null ) { // 仅打印当前节点的value,彻底避免循环引用 override fun toString(): String = "Node(value=$value)" // 可选:如果需要显示下一个节点的数值,而非完整对象 // override fun toString(): String = "Node(value=$value, nextValue=${next?.value ?: "null"})" }
2. 将data class改为普通class
如果不需要data class自动生成的equals()、hashCode()等方法,可以直接改成普通class,然后按需实现toString():
class Node( var value: Int, var next: Node? = null, var prev: Node? = null ) { override fun toString(): String = "Node(value=$value)" }
3. 修复遍历代码的NPE问题
将do-while循环改为安全的while循环,避免强制非空断言:
fun makeLinkedList() { // ... 节点初始化代码不变 ... var it: Node? = root while (it != null) { println(it.toString()) it = it.next } }
内容的提问来源于stack exchange,提问作者gmmo
相关产品推荐
相关产品推荐

