SortedLinkedList自定义Iterator删除数据失败问题求助
问题解决:SortedLinkedList自定义Iterator无法删除元素的修复方案
核心问题分析
自定义Iterator未实现
remove()方法
你编写的SortedListIterator仅实现了hasNext()和next(),但Iterator接口的默认remove()方法会抛出UnsupportedOperationException,导致调用iter.remove()时根本没有执行实际的删除逻辑。store方法中重复调用
next()导致元素跳过
删除逻辑的循环里,你先后调用了两次iter.next():Payment pay = iter.next(); if (iter.next().getP_ID().equals(paymentID)) { ... }这会让迭代器指针每次跳过两个元素,要么错过目标元素,就算匹配到,删除的也是当前指针的下一个元素,逻辑完全错乱。同时,你在调用
display()之后复用了同一个迭代器,此时指针已经走到链表末尾,后续遍历根本拿不到元素。SortedLinkedList的
remove(T anEntry)方法有逻辑缺陷
删除头节点时没有减少numberOfEntries计数,且只有删除中间节点才返回true,删除头节点后直接跳出,导致头节点删除操作实际未生效。
修复步骤与代码修改
1. 为自定义Iterator实现remove()方法
要实现删除功能,Iterator需要记录上一次next()返回的节点及其前驱节点,以此修改链表指针。修改SortedListIterator:
private class SortedListIterator implements Iterator<T> { private Node currentNode = firstNode; private Node lastReturnedNode = null; // 记录上一次next返回的节点 private Node prevNode = null; // 记录上一次节点的前驱 @Override public boolean hasNext() { return currentNode != null; } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } prevNode = lastReturnedNode; lastReturnedNode = currentNode; T data = currentNode.data; currentNode = currentNode.next; return data; } @Override public void remove() { if (lastReturnedNode == null) { throw new IllegalStateException(); } // 执行删除操作 if (lastReturnedNode == firstNode) { firstNode = firstNode.next; } else { prevNode.next = lastReturnedNode.next; } lastReturnedNode = null; // 防止重复调用remove numberOfEntries--; } }
2. 修正store方法中的删除逻辑
移除重复的next()调用,并将迭代器初始化移到输入操作之后:
public void store() { display(); System.out.println("\nRemove Record Function"); System.out.println("=============================="); System.out.printf("Fill the payment ID to remove : "); String paymentID = scan.nextLine(); // 重新初始化迭代器,确保从链表头部开始遍历 Iterator<Payment> iter = payment.getIterator(); while (iter.hasNext()) { Payment pay = iter.next(); if (pay.getP_ID().equals(paymentID)) { System.out.print("ok"); iter.remove(); break; // 若需删除所有匹配项,可移除break } } display(); }
3. 修复SortedLinkedList的remove(T anEntry)方法
补全删除头节点时的计数更新与返回逻辑:
public boolean remove(T anEntry) { if (firstNode == null) { return false; } Node beforeNode = null; Node currentNode = firstNode; while (currentNode != null && currentNode.data.compareTo(anEntry) < 0) { beforeNode = currentNode; currentNode = currentNode.next; } if (currentNode != null && currentNode.data.equals(anEntry)) { if (currentNode == firstNode) { firstNode = firstNode.next; } else { beforeNode.next = currentNode.next; } currentNode = null; numberOfEntries--; // 统一处理计数减少 return true; } return false; }
测试验证
修改后运行程序,输入目标Payment ID,即可正确匹配并删除对应元素,display()方法会展示删除后的链表状态,计数也会同步更新。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

