删除双向链表任意节点时触发异常,求技术解决方案
双向链表删除节点的异常问题修复
直接给你指出代码里的核心问题和修复方案:
1. 逻辑运算符错误触发空指针
循环条件里用了&(按位与),这会导致即使temp已经是null,仍会执行temp.data != data,直接触发空指针异常。必须换成短路逻辑与&&,它会在temp == null时直接终止后续判断:
// 原错误代码 for (; temp != null & temp.data != data; temp = temp.next); // 修复后 for (; temp != null && temp.data != data; temp = temp.next);
2. 引用类型比较用错运算符
如果泛型T是引用类型(比如String、自定义对象),用==比较data是错误的——==比较的是对象内存地址,不是实际内容,会导致找不到目标节点或误判。要换成equals()方法,同时注意处理data为null的情况:
// 替换所有data == xxx.data的判断 // 单个节点场景 if (this.head == this.tail && (data == null ? this.head.data == null : data.equals(this.head.data))) // 头节点场景 else if (data == null ? this.head.data == null : data.equals(this.head.data)) // 循环条件 for (; temp != null && !(data == null ? temp.data == null : data.equals(temp.data)); temp = temp.next);
3. 辅助方法的边界校验
要确保deleteFromStart()和deleteFromEnd()的逻辑正确,避免后续异常:
deleteFromStart():移动head到head.next后,要把新head的prev设为null;如果移动后head为null,必须同步把tail设为null。deleteFromEnd():移动tail到tail.prev后,要把新tail的next设为null;如果移动后tail为null,必须同步把head设为null。
修复后的完整delete方法参考
public void delete(T data) { if (!isEmpty()) { // 处理仅单个节点的场景 if (this.head == this.tail) { boolean isMatch = (data == null && this.head.data == null) || (data != null && data.equals(this.head.data)); if (isMatch) { this.head = this.tail = null; } return; } // 处理头节点场景 boolean headMatch = (data == null && this.head.data == null) || (data != null && data.equals(this.head.data)); if (headMatch) { this.deleteFromStart(); return; } // 查找目标节点 DllNode temp = this.head; while (temp != null) { boolean nodeMatch = (data == null && temp.data == null) || (data != null && data.equals(temp.data)); if (nodeMatch) { break; } temp = temp.next; } // 处理找到的节点 if (temp != null) { if (temp == this.tail) { this.deleteFromEnd(); } else { temp.prev.next = temp.next; temp.next.prev = temp.prev; } } } }
内容的提问来源于stack exchange,提问作者Howard Teh
相关产品推荐
相关产品推荐

