Nested list iterations followed by deletion

I am trying to iterate over a list while it already goes through it (nested loops). Consider the following code:

ArrayList<Integer> list = new ArrayList<Integer>(); // add some values to it for(int i : list) { // ConcurrentModificationException Iterator iterator = list.iterator(); while(iterator.hasNext()) { int n = iterator.next(); if(n % i == 0) { iterator.remove(); } } } 

The above example throws a ConcurrentModificationException. The condition for deleting an element is, of course, just an example.

I'm sure I just missed something; but how should I build a loop that achieves the same in Java without throwing an exception?

+4
source share
7 answers

Obviously, it modifies the list when you iterate over it, invoking execution. You can use another list to save the list of items that you want to remove and delete them at the end.

 ArrayList<Integer> list = new ArrayList<Integer>(); // add some values to it ArrayList<Integer> del = new ArrayList<Integer>(); // Elements to be deleted for(int i : list) { // ConcurrentModificationException Iterator iterator = list.iterator(); while(iterator.hasNext()) { int n = iterator.next(); if(n % i == 0) { del.add(n); } } } list.removeALL(del); 
+4
source

Make an external iteration iterate over a copy of the list.

 for (int i : new ArrayList<>(list)) { Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { int n = iterator.next(); if (n % i == 0) { iterator.remove(); } } } 
+2
source

You get a ConcurrentModificationException because by doing a for loop you are trying to modify list .

I'm not sure if the following is an elegant solution or not, but something like below might work:

  Iterator<Integer> iterator = list.iterator(); int i=1; while (iterator.hasNext()) { int n = iterator.next(); if (n % i == 0) { iterator.remove(); } i++; } 
+1
source

You cannot remove an item from a list that is iterated. One option is to add the items you need to another list. Finally, you have a list of items that you need. Or you can iterate over a clone of the source list.

0
source

I am doing something very similar to you. hav e in this code.

 out:for(int h=0; h<tempAl.size(); h++) { if(tempAl.get(0).split("\\s")[0].equals("OFF")){ tempAl.remove(0); h=-1; continue; } if(tempAl.get(h).split("\\s")[0].equals("ON")){ ONTime= tempAl.get(h); ///rest fof the code } 

I think you can also change the index after removing an element from arraylist.

0
source

I have not tried but use:

 List<Integer> list = new ArrayList<Integer>(); // add some values to it for(Iterator<Integer> iterator1 = list.iterator(); iterator1.hasNext();) { int i = iterator1.next(); for(Iterator<Integer> iterator2 = list.iterator(); iterator2.hasNext();){ int n = iterator.next(); if(n % i == 0) { iterator2.remove(); } } } 

or if it still raises a ConcurrentModificationException (I'm not sure what will happen if you use 2 iterators supported by the same list), and then use:

 List<Integer> list = new ArrayList<Integer>(); // add some values to it for(int i : new ArrayList(list)){ // copy list ... } 
0
source

foreach Java syntax hides the iterator, but hiding it makes it impossible to call the remove method on this.

So, I would do:

 ArrayList<Integer> list = new ArrayList<Integer>(); // add some values to it int count = 0; for(Iterator<Integer> it = list.iterator();it.hasNext();count++){ //increments count++ Integer currentInt = it.next(); if(currentInt % count == 0){ it.remove(); } } 

You can see that the same function is achieved without the need for a secondary iterator.

You cannot iterate over the same list at the same time. To summarize, the modcount variable modcount used to detect an unexpected change in itself each time the list changes or repeats in parallel. Thus leading to a ConcurrentModificationException . It appears very often with a multi-threaded environment, and developers should be aware of this.

Also, prefer to use a for loop instead of a while to iterate through the collection.

Why?

Because with the while method, you allow the iterator object to remain in scope after the loop, whereas with for it is not. A simple it.next() callback would end with a NoSuchElementException .

Best stored;)

0
source

Source: https://habr.com/ru/post/1436644/


All Articles