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 が残ります。

2 回目の反復でiは、1 になり、サイズは 4 になり、C を削除します (現在は位置 1 にあります)。B、D、Eが残ります。

3 回目の反復でiは、2 になり、サイズは 3 になり、E を削除します (現在は位置 2 にあります)。それはB、Dを残します。

次はi3 になり、サイズは 2 になり、ループは終了します。

オプション:

  • 並べ替えを避けるために (そして効率を向上させるために) 、 startではなくendから削除します。
  • サイズが 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. 現在は 2 であるためi、i > list.size() であるため、ループが停止します。

リストにはまだ 1 つの要素があります。

于 2013-10-03T08:21:59.607 に答える
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 に答える
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);
}

編集:書くのを忘れました:

これは、 iteratorを使用せずにループしながらリストを編集することを強くお勧めしません。そう

  • リストをクリアするかList.clear();
  • またはIterator、Iterator#remove(); で要素を削除します。いくつかの要素のみを削除したい場合。
于 2013-10-03T08:22:53.157 に答える
0

他の人が言ったように、問題が何であるかを理解する必要がありますが、オプションi++として、次のようにループから削除するだけでコードを機能させることができます。

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

出力:

deleted item: 20
deleted item: 30
deleted item: 40
0
after try catch: 
于 2013-10-03T08:51:09.993 に答える
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 に答える