为什么我的 ArrayList.remove(id) 调用不起作用?

2022-09-04 06:36:29

我有一个 ArrayList,其中包含许多我要删除的项目。我有要删除的项目的ID存储在另一个列表中。图示以下代码应该可以正常工作,但由于某种原因,remove() 调用返回一个 false 值:

  ArrayList<Integer> toRemove = new ArrayList<Integer>();
  ArrayList<JCheckBox> al = new ArrayList<JCheckBox>();

  /* Code that adds a bunch of items to al, and a few integers to toRemove */

  System.out.println("Size before removing: " + al.size());
  for (int i = toRemove.size() - 1; i >= 0; i--) {
    System.out.println("Removing id: " + toRemove.get(i) + ": ");
    System.out.println(al.get(toRemove.get(i)));
    System.out.println(al.remove(toRemove.get(i)));
  }
  System.out.println("Size after removing: " + al.size());

如果 get() 调用也返回了一个 false 值,我会得到它,但它实际上返回了有问题的对象。我在这里错过了什么?

上述代码的输出:

Size before removing: 3
Removing id: 2: 
javax.swing.JCheckBox[...]
false
Size after removing: 3

答案 1

我的猜测是,您遇到了一个问题,即两者都重载了 和 ,而只采用 .尝试。remove()intObjectget()intremove(toRemove.get(i).intValue())

remove(Object)from 将搜索列表并删除给定的对象,该对象不会存在,因为您正在向它发送一个,并且列表只有 s。您正在尝试调用 ,但是因为您给它一个 ,所以 Object 重载被调用。通过将 转换为 ,可以避免此问题AbstractCollectionIntegerJCheckBoxremove(int)IntegerIntegerint

另外,您能始终确保 toRemove 中的 Id 始终等于索引吗?如果 toRemove 不是按从最大到最不的顺序排列的,则不会。


答案 2

您的代码存在两个问题。首先,调用了错误的“toRemove”方法。当您调用“toRemove.get(i)”时,返回值会自动装箱到java.lang.Integer中,而不是int。因此,调用java.util.List#remove(Object)而不是java.util.List#remove(int)。它尝试删除 Integer 对象,并返回 false。如果将 Integer 转换为 int,则将调用所需的方法。

第二个问题:每次删除列表中的某个元素时,所有后续元素的索引都会发生变化,因为这些元素会向下“移位”。有几种方法可以解决这个问题。一种是按降序对索引列表进行排序。另一种方法是使用一组索引,创建一个新数组,然后仅将索引不在集合中的那些元素复制到新数组中。