haind
haind

Reputation: 1002

Java ArrayList issue with try-catch

I want to clear an ArrayList in try-catch. I do know that we can do it with clear() method.But when I try clear every items with for loop. It show below result:

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);
        }
    }
}

and the result is:

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

I thinked It must be empty ArrayList. What trouble I have is?

Upvotes: 1

Views: 5962

Answers (7)

Jon Skeet
Jon Skeet

Reputation: 1502196

The problem has nothing to do with try/catch, and everything to do with this loop:

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

That will only remove every other element. (It will also print different items than the ones it actually deletes, which is odd...)

Suppose you start off with A, B, C, D, E.

On the first iteration, i will be 0, the size will be 5, and you'll remove A. That will leave B, C, D, E.

On the second iteration, i will be 1, the size will be 4, and you'll remove C (which is now at position 1). That will leave B, D, E.

On the third iteration, i will be 2, the size will be 3, and you'll remove E (which is now at position 2). That will leave B, D.

Next, i will be 3, the size will be 2, and the loop will terminate.

Options:

  • Remove from the end instead of the start, to avoid reordering (and improve efficiency)
  • Always remove from the front, until the size is 0

For example:

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

Or (less efficient):

while (list.size() > 0) {
    System.out.println("deleted item: " + list.get(0));
    list.remove(0);
}

Upvotes: 4

commit
commit

Reputation: 4807

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: 

Upvotes: 0

Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31245

/*
 * 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);
}

EDIT : I forgot to write :

This is highly discouraged to edit a list while looping on it without using an iterator. So

  • Either clear the list with List.clear();
  • Or use an Iterator and remove elements with Iterator#remove(); if you want to remove only several elements.

Upvotes: 1

Sufian Latif
Sufian Latif

Reputation: 13356

The problem is in the part i < list.size(). Each time you delete an item, the size of the list decreases by 1, and i also increases by 1. So i gets larger than list.size() before the list is empty.

What actually happens is:

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

Upvotes: 0

Fabrice Jammes
Fabrice Jammes

Reputation: 3205

Replacing catch code by this should work and simplify your code :

catch (Exception e) {
        list=new ArrayList();
    }

Upvotes: 0

angel_navarro
angel_navarro

Reputation: 1777

you cannot do this:

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

Because every time you delete an element, list size changes, so the last element of the list will not change.

Upvotes: 1

&#201;tienne Miret
&#201;tienne Miret

Reputation: 6660

You need to keep in mind that the size of your list changes after each call to list.remove.

So, the event are the following:

  1. List size is 3.
  2. You call list.remove(0)
  3. List size is 2.
  4. You call list.remove(1)
  5. List size is 1.
  6. Since i is now 2, i > list.size(), so loop stops.

You still have one element in your list.

Upvotes: 1

Related Questions