0

I know that removing an element from a list while iterating it is not recommended.
You better use iterator.remove(), java streams, or copy the remove to an external list.

But this simple code just works:

 static List<Integer> list = new ArrayList<Integer>();
 ...
 private static void removeForI() {
    for (int i = 0; i < 10; i++) {
        if (i == 3) {
            list.remove(i);
            continue;
        }
        System.out.println(i);
    }
 }

Is it safe to use it?

8
  • 1
    Yes, assuming the list has at least 4 elements to start with. Commented Apr 16, 2018 at 21:56
  • Yes, it's fine if you're not using an iterator. Just make sure your index is where you want it to be after removing. Commented Apr 16, 2018 at 21:56
  • It'll skip the element that starts at index 4. Commented Apr 16, 2018 at 21:57
  • 4
    @LouisWasserman It's a trick question. It's just printing i, not the element at index i. Result is that 4th element is removed from list, and that code prints 0 1 2 4 5 6 7 8 9, skipping the number 3, but not skipping any element. Commented Apr 16, 2018 at 21:57
  • 1
    Well, if you know what you do, you can definitely do it like you have shown. It's just that its often a source for potential bugs because people tend to forget that they need to take care if they do that. That's why the Iterator implementation throws a ConcurrentModifcationException if you iterate over it and modify the underlying collection. Commented Apr 16, 2018 at 22:17

4 Answers 4

3

You need to think about how list.remove(index) works. When remove(idx) gets called, the element at idx index gets deleted and all the next elements gets shifted to left. So, suppose you have a list containing 2, 3, 3, 4, 5. Now you want to remove all the 3s from this list. But if you use your current approach, it will remove only the first occurrence of 3. Because after removing 1st occurrence of 3 which is at position 1 your contents will get shifted to left and will be like this 2, 3, 4, 5. But now your for loop will increment the current index to 2 which contains 4 and not 3. That is why it is not advised to remove items while iterating, Because index of items gets changed after each removal.

Edit: Also if you are using a constant value in loop break condition like in above example i<10; you might get ArrayIndexOutOfBounds exception.

Sign up to request clarification or add additional context in comments.

1 Comment

Last edit is exactly right. @ScalaNooB Just try System.out.println(list.get(i)); instead of System.out.println(i); inside your loop.
0

Even though it works under the condition people have pointed out, I would only use it temporarily and change it to:

private static void removeForI() {
    list.remove(3);
    list.foreach(System.out::println);
}

There is no need to check if i==3, simply remove it before the for loop.

3 Comments

perhaps condition is not that simple to remove only 3-rd element. Otherwise in the example there is no reason to keep looping when 3-rd element removed... there can be just break; instead of continue;
I agree on the condition. But the continue makes sure all the following elements are printed as well, which a break couldn't do. Nevertheless, I would never try to solve this like ScalaNooB in the first way.
h-m-m... example does not print following elements. :-) it prints indexes - System.out.println(i); if print following elements code is broken.
0

It looks like that loop will be having a different conditional later on as otherwise you can simply do as JoschJava stated.

However if you truly want to iterate through all of your elements and remove a specific one during the loop, you may want to shift the index backwards afterwards. If that is the case, I would add this at the end of your conditional body:

i -= 1;

Comments

0

It isn't safe at all. When you know you might temper the list during iteration, convert your list object into Iterator object then use its methods : hasNext, next, remove...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.