1

我想在 try-catch 中清除一个 ArrayList。我知道我们可以用方法来做到这一点。但是clear()当我尝试用 for 循环清除每个项目时。它显示以下结果:

public class ArrayListTryCatch {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList();
        int oldsize = list.size();
        try {
            list.add(20);
            list.add(30);
            list.add(40);
            int wrongDivide = 1 / 0;
        } catch (Exception e) {
            for (int i = 0; i < list.size(); i++) {
                System.out.println("deleted item: " + list.get(oldsize));
                list.remove(i);
            }
        }
        System.out.println(list.size());
        System.out.println("after try catch: ");
        for (Integer e : list) {
            System.out.println(e);
        }
    }
}

结果是:

deleted item: 20
deleted item: 30
1
after try catch: 
30

我认为它必须是空的 ArrayList。我有什么麻烦?

4

7 回答 7

4

问题与 try/catch 无关,与此循环有关:

for (int i = 0; i < list.size(); i++) {
    System.out.println("deleted item: " + list.get(oldsize));
    list.remove(i);
}

那只会删除所有其他元素。(它还会打印与实际删除的项目不同的项目,这很奇怪......)

假设您从 A、B、C、D、E 开始。

在第一次迭代中,i将为 0,大小为 5,您将删除 A。这将留下 B、C、D、E。

在第二次迭代中,i将为 1,大小为 4,您将删除 C(现在位于位置 1)。那将留下B,D,E。

在第三次迭代中,i将为 2,大小为 3,并且您将删除 E(现在位于位置 2)。那将离开B,D。

接下来,i将是 3,大小将是 2,循环将终止。

选项:

  • end而不是start删除,以避免重新排序(并提高效率)
  • 总是从前面移除,直到大小为 0

例如:

// Work from the back...
for (int i = list.size() - 1; i >= 0; i--) {
    System.out.println("deleted item: " + list.get(i));
    list.remove(i);
}

或(效率较低):

while (list.size() > 0) {
    System.out.println("deleted item: " + list.get(0));
    list.remove(0);
}
于 2013-10-03T08:22:01.663 回答
1

您需要记住,每次调用 list.remove 后,列表的大小都会发生变化。

因此,事件如下:

  1. 列表大小为 3。
  2. 你打电话list.remove(0)
  3. 列表大小为 2。
  4. 你打电话 list.remove(1)
  5. 列表大小为 1。
  6. 由于i现在是 2,i > list.size(),所以循环停止。

您的列表中仍有一个元素。

于 2013-10-03T08:21:59.607 回答
1
/*
 * On the first step, you delete 20.
 * So the list is [30, 40]
 *
 * On the second step, you delete at index 1
 * so you delete 40.
 *
 * Then i becomes > list.size() => the loop stops
 */
for (int i = 0; i < list.size(); i++) {
  System.out.println("deleted item: " + list.get(oldsize));
  list.remove(i);
}

编辑:我忘了写:

非常不鼓励在不使用迭代器的情况下循环编辑列表。所以

  • 要么清除列表List.clear();
  • 或者使用IteratorIterator#remove(); 和删除元素;如果您只想删除几个元素。
于 2013-10-03T08:22:53.157 回答
1

你不能做这个:

for (int i = 0; i < list.size(); i++) {
System.out.println("deleted item: " + list.get(oldsize));
list.remove(i);
}

因为每次删除一个元素,列表大小都会改变,所以列表的最后一个元素不会改变。

于 2013-10-03T08:22:45.563 回答
0

As said by others you should got idea what the problem is, but as optional you can make your code work by simply removing i++ from your loop, like:

for (int i = 0; i < list.size();) {
        System.out.println("deleted item: " + list.get(oldsize));
        list.remove(i);
}

Output:

deleted item: 20
deleted item: 30
deleted item: 40
0
after try catch: 
于 2013-10-03T08:51:09.993 回答
0

用这个替换 catch 代码应该可以工作并简化您的代码:

catch (Exception e) {
        list=new ArrayList();
    }
于 2013-10-03T08:22:54.010 回答
0

问题出在零件上i < list.size()。每次删除一个项目时,列表的大小会减少1i也会增加1。所以i变得比list.size()列表为空之前更大。

实际发生的是:

1. i = 0, list is [20, 30, 40], list.size() returns 3, i < 3 and 20 is deleted
2. i = 1, list is [30, 40], list.size() returns 2, i < 2 and 40 is deleted
3. i = 2, list is [30], list.size() returns 1, i > 1 and 30 is NOT deleted,
   loop breaks here
于 2013-10-03T08:22:42.447 回答