You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SortedLinkedList自定义Iterator删除数据失败问题求助

问题解决:SortedLinkedList自定义Iterator无法删除元素的修复方案

核心问题分析

  1. 自定义Iterator未实现remove()方法
    你编写的SortedListIterator仅实现了hasNext()和next(),但Iterator接口的默认remove()方法会抛出UnsupportedOperationException,导致调用iter.remove()时根本没有执行实际的删除逻辑。

  2. store方法中重复调用next()导致元素跳过
    删除逻辑的循环里,你先后调用了两次iter.next():

    Payment pay = iter.next();
    if (iter.next().getP_ID().equals(paymentID)) { ... }
    

    这会让迭代器指针每次跳过两个元素,要么错过目标元素,就算匹配到,删除的也是当前指针的下一个元素,逻辑完全错乱。同时,你在调用display()之后复用了同一个迭代器,此时指针已经走到链表末尾,后续遍历根本拿不到元素。

  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:18:27