Java的List容器使用remove()方法时应注意int和Integer的区别!!

今天我在写最小生成树的Prim算法的时候,发现了一个问题,我觉得值得探讨一下:
我使用一个ArrayList储存未加入最小生成树的节点的index(整数类型),每一次循环找到一个离已加入最小生成树的节点集合“最近”的节点,将它的index从这个ArrayList中删除。在检查程序逻辑无误后运行,发现抛出了java.lang.IndexOutOfBoundsException

原因

简单检查后我发现ArrayList的remove方法是一个重载的(overloaded)方法。即:
这里写图片描述
从IDEA的代码提示可以看到,remove方法有两种参数类型,一种是int类型,一种是Object类型。如果你的ArrayList指定的元素类型是Integer,那么你使用remove方法移除一个Integer类型的元素的时候,程序可能理解成移除由该数字指定位置上的元素。
我进一步猜想线性容器应当都有通过index删除元素的方法,因此我查看了List接口的定义,其中果不其然有两个remove方法:
1. 按index移除元素:

E remove(int index);


    // Search Operations

    /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     *
     * @param o element to search for
     * @return the index of the first occurrence of the specified element in
     *         this list, or -1 if this list does not contain the element
     * @throws ClassCastException if the type of the specified element
     *         is incompatible with this list
     *         (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null and this
     *         list does not permit null elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>)
     */

2.按元素移除:

boolean remove(Object o);


    // Bulk Modification Operations

    /**
     * Returns <tt>true</tt> if this list contains all of the elements of the
     * specified collection.
     *
     * @param  c collection to be checked for containment in this list
     * @return <tt>true</tt> if this list contains all of the elements of the
     *         specified collection
     * @throws ClassCastException if the types of one or more elements
     *         in the specified collection are incompatible with this
     *         list
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified collection contains one
     *         or more null elements and this list does not permit null
     *         elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see #contains(Object)
     */

解决

因此,在编程的时候,应当严格区分Integer和int。如果你要从一个元素类型为Integer的List中删除一个元素(按照元素而不是index删除),你应该用以下两种方式的其中一种:

int elementToBeRemoved = 0;
list.remove((Integer)elementToBeRemoved);

Integer elementToBeRemoved = 0;
list.remove(elementToBeRemoved);

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是使用 List 和 Map 实现拓扑排序的 Java 代码,注释已经加上: ```java import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class TopologicalSort { public static void main(String[] args) { // 构建图,key 为节点,value 为该节点的后继节点列表 Map<Integer, List<Integer>> graph = new HashMap<>(); graph.put(1, new ArrayList<>()); graph.put(2, new ArrayList<>()); graph.put(3, new ArrayList<>()); graph.put(4, new ArrayList<>()); graph.put(5, new ArrayList<>()); graph.get(1).add(2); graph.get(1).add(3); graph.get(2).add(4); graph.get(3).add(4); graph.get(4).add(5); // 拓扑排序,返回排序后的节点列表 List<Integer> sorted = topologicalSort(graph); // 输出排序结果 System.out.println(sorted); } /** * 使用 List 和 Map 实现拓扑排序 * @param graph 待排序的有向图,key 为节点,value 为该节点的后继节点列表 * @return 排序后的节点列表 */ public static List<Integer> topologicalSort(Map<Integer, List<Integer>> graph) { // 统计每个节点的入度 Map<Integer, Integer> inDegree = new HashMap<>(); for (Map.Entry<Integer, List<Integer>> entry : graph.entrySet()) { int node = entry.getKey(); inDegree.putIfAbsent(node, 0); // 初始化节点的入度为 0 for (int successor : entry.getValue()) { inDegree.put(successor, inDegree.getOrDefault(successor, 0) + 1); // 统计后继节点的入度 } } // 将入度为 0 的节点加入队列 List<Integer> queue = new ArrayList<>(); for (Map.Entry<Integer, Integer> entry : inDegree.entrySet()) { if (entry.getValue() == 0) { queue.add(entry.getKey()); } } // 拓扑排序 List<Integer> sorted = new ArrayList<>(); while (!queue.isEmpty()) { int node = queue.remove(0); // 取出队首节点 sorted.add(node); // 将节点加入排序列表 for (int successor : graph.get(node)) { // 遍历后继节点 int newDegree = inDegree.get(successor) - 1; // 将后继节点的入度减 1 inDegree.put(successor, newDegree); if (newDegree == 0) { // 如果后继节点的入度为 0,则加入队列 queue.add(successor); } } } if (sorted.size() != graph.size()) { // 如果排序列表的长度小于节点数,说明图中存在环 throw new IllegalArgumentException("The graph contains a cycle"); } return sorted; } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值