-1

Here is my code:

public class Test {
    public static void main(String[] args){
        ArrayList<Integer> list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(2);
        list.add(2);
        list.add(5);
        int inteval = 0;
        Iterator<Integer> it = list.iterator();
        for(;it.hasNext();){
            Integer n = it.next();
            list.remove(n);
            if (list.contains(n-inteval)){
                list.remove(list.indexOf(n-inteval));
                if (list.contains(n-inteval-inteval)){
                    list.remove(list.indexOf(n-inteval-inteval));
                }else{
                    list.add(n-inteval);
                    list.add(n);
                }
            }
        }
    }
}

this code will throw ConcurrentModificationException, I have tryed to use CopyOnWriteArrayList, but I found it.next() returns a value the removed by last time! how can I fixed it?

Arnab Nandy
  • 6,472
  • 5
  • 44
  • 50
Jason Young
  • 575
  • 3
  • 16
  • Possible duplicate of [Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop](http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – Raedwald Mar 28 '16 at 14:50

2 Answers2

0

It is because you are doing the following:

    Iterator<Integer> it = list.iterator();
    for(;it.hasNext();){
        Integer n = it.next();
        list.remove(n);

While using the Iterator, you cannot modify the list with the list.remove(), list.add() functions. To remove elements using an iterator, you need to call it.remove(), which removes the element you obtained with it.next(). If you truly want to do this, then you should do the following:

    for(int i = 0; i < list.size(); i++){
        Integer n = list.get(i);
    ...

Although you also need to ensure that as you modify the list and the elements get pushed back and forth, you check an element only once. It'd probably be easier for you to just construct a different list with the elements you need.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • I don't think this is a good solution, cause list.size() will always change! – Jason Young Sep 15 '14 at 10:28
  • Yeah, you're right, and when you remove the current element, then you need to adjust the index to be `i--;` and stuff. I'm confused on what exactly you are trying to do, so I cannot tell you how to make a better solution. – EpicPandaForce Sep 15 '14 at 10:36
  • https://code.google.com/codejam/contest/4214486/ I've got the right answer, but I would to see your answer. can you? – Jason Young Sep 15 '14 at 13:53
0

You should not modify the list after getting the Iterator using any of the list method.

As already pointed out - call remove method on the Iterator instance.

for example -

public class Test {
    public static void main (String... at) throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(2);
        list.add(2);
        list.add(5);

        Iterator<Integer> it = list.iterator();
        //below while will remove every element from the list
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
        //this will leave 5 as the only element in list
        /*while (it.hasNext()) {
            if (it.next() != 5) {
                it.remove();
            }
        }*/
        //below loop will remove all the occurences of 1 or 2
        while (it.hasNext()) {
            Integer number = it.next();
            if (number == 1 || number == 2) {
                it.remove();
            }
        }
        System.out.println(list.toString());
    }
}
Tirath
  • 2,294
  • 18
  • 27