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

Java自定义Graph类中如何删除HashMap所存ArrayList内的Arch对象

问题原因
  • 类型定义不兼容:你的Graph类中arch成员的泛型定义为HashMap<N,ArrayList<T>>,但你实际存储的是Arch<N,T>类型的对象,T是Arch的标签类型,此处定义存在错误,运行时类型擦除会导致取值、删除逻辑异常。
  • 遍历删除逻辑错误:Java增强for循环(for-each)底层基于迭代器实现,直接调用ArrayList的remove方法会破坏迭代器的遍历规则,轻则出现游标偏移导致漏删、无修改效果,重则抛出ConcurrentModificationException异常。
  • 判断条件逻辑错误:你要删除起点为start、终点为end的边,判断条件应该为a.start.equals(start) && a.end.equals(end),你写的||逻辑不符合需求。同时如果N是自定义类型,不能用==比较对象内容,必须调用equals方法。
  • 场景逻辑缺失:如果你的图是无向图(oriented为false),还需要同步删除end节点对应列表中起点为end、终点为start的边,同时删除成功后需要更新nArch计数。
修复实现

首先修正Graph类的arch成员泛型定义:

private HashMap<N,ArrayList<Arch<N,T>>> arch;

修正后的deleteArch方法:

public void deleteArch(N start, N end) {
    // 空校验避免空指针异常
    if (!arch.containsKey(start)) {
        return;
    }
    ArrayList<Arch<N,T>> archsForNode = arch.get(start);
    // 使用迭代器执行删除避免并发修改问题
    Iterator<Arch<N,T>> iterator = archsForNode.iterator();
    int deleteCount = 0;
    while (iterator.hasNext()) {
        Arch<N,T> a = iterator.next();
        if (a.start.equals(start) && a.end.equals(end)) {
            iterator.remove();
            deleteCount++;
            // 如果不需要保留重复边,此处可直接break提升性能
        }
    }
    // 无向图需要同步删除反向边
    if (!oriented && arch.containsKey(end)) {
        ArrayList<Arch<N,T>> reverseArchs = arch.get(end);
        Iterator<Arch<N,T>> reverseIt = reverseArchs.iterator();
        while (reverseIt.hasNext()) {
            Arch<N,T> a = reverseIt.next();
            if (a.start.equals(end) && a.end.equals(start)) {
                reverseIt.remove();
                deleteCount++;
            }
        }
    }
    // 更新边的总计数
    nArch -= deleteCount;
}
注意事项

自定义节点类型N必须重写equals和hashCode方法,否则内容相同的对象会被识别为不同对象,导致匹配删除失败。

内容的提问来源于stack exchange,提问作者Sof

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:06:01