Java双向链表节点新增与打印功能代码问题咨询
Java双链表代码问题解答
1. Lista访问Node私有属性的方法
Node类的num、tail、head属性都是private修饰,仅允许Node类自身内部访问,Lista类要操作这些属性有两种可行方案:
- 为Node类的属性添加对应的get、set方法,Lista通过调用公共方法读写属性值,符合面向对象封装规范
- 将Node类属性的访问修饰符从
private改为默认访问权限(不写修饰符),只要Node和Lista在同一个包下,Lista就能直接访问属性,这种方式写法简单但破坏封装性,不推荐在正式项目中使用
另外原代码存在属性归属设计错误:head(链表头节点)、tail(链表尾节点)是整个链表的全局属性,应该定义在Lista类中,而不是每个Node节点都存一份。Node节点只需要存储自身数值、前驱节点引用、后继节点引用即可。
2. 现有代码无法正常实现预期功能
现有代码连编译阶段都无法通过,更不可能正常运行,核心问题如下:
- Lista类中直接使用
head、tail变量,但类中从未定义这两个变量,会直接触发「找不到符号」的编译错误 - Node类错误存储了全局链表的头、尾引用,属性设计逻辑混乱
add方法仅处理了链表为空时的逻辑,非空场景下没有将新节点和现有链表建立关联,根本无法实现多节点挂载display方法的循环中从未移动遍历指针,就算能运行也会触发死循环,一直打印第一个节点的值
3. 修正后可正常运行的代码
首先调整属性命名避免歧义:将Node类中指向后继的原head属性改名为next,指向前驱的原tail属性改名为prev,添加必要的get/set方法:
public class Node { private int num; private Node prev; // 前驱节点 private Node next; // 后继节点 public Node (int num) { this.num = num; this.prev = null; this.next = null; } public int getNum() { return num; } public Node getPrev() { return prev; } public void setPrev(Node prev) { this.prev = prev; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } }
之后修正Lista类,在类中定义全局的头、尾节点引用,补全add方法的节点挂载逻辑,修复display方法的遍历逻辑:
public class Lista { private Node head; // 链表头节点 private Node tail; // 链表尾节点 public Lista () { head = null; tail = null; } public void add (int num) { Node newNode = new Node(num); // 空链表场景:新节点同时作为头、尾节点 if (head == null) { head = newNode; tail = newNode; return; } // 非空链表场景:新节点挂到当前尾节点之后 newNode.setPrev(tail); tail.setNext(newNode); tail = newNode; } public void display () { Node current = head; while(current != null) { System.out.print(current.getNum() + " "); // 指针移动到下一个节点,避免死循环 current = current.getNext(); } } }
原Demo类不需要修改,运行后会正常输出3 9 7 ,符合新增节点、遍历打印的预期。
内容的提问来源于stack exchange,提问作者Max Ringnalda
相关产品推荐
相关产品推荐

