Java: changing the properties of an iterative object while iterating over it

The following code is only for an example of a problem:

public static void main(String[] args) { Collection<Integer> src = new ArrayList<Integer>(); Collection<Integer> dest = new ArrayList<Integer>(); src.add(2); src.add(7); src.add(3); src.add(2201); src.add(-21); dest.add(10); while (src.size() != 0) { for (int i : dest) { int min = Collections.min(src); dest.add(min); src.remove(min); } } } 

What I want to do is move everything from src to dest in a specific order. (Here, this is what is the minimum value, but it is just a simplification from my real problem.) However, I change dest when iterating over it and I get the following error:

 Exception in thread "main" java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(Unknown Source) at java.util.AbstractList$Itr.next(Unknown Source) at nth23.experimental.MoveBetweenSets.main(MoveBetweenSets.java:25) 

How can I get around this?

0
source share
6 answers

Is there a reason why you cannot just copy the source list to the mailing list and then sort it?

  Collection <Integer> dest = new ArrayList <Integer> (src);
 Collections.sort (dest);
+2
source

This is a workaround:

 while (!src.isEmpty()) { int min = Collections.min(src); dest.add(min); src.remove(min); } 

But it can even make the situation worse. Be more specific (as John said).

+2
source

You can remove from the collection (well, some collections) iterate over it using iterator.remove() - but you can't usually add to it.

However, as newacct notes in the comments, the ListIterator interface includes the add method, so you can change your code as follows:

 public static void main(String[] args) { Collection<Integer> src = new ArrayList<Integer>(); List<Integer> dest = new ArrayList<Integer>(); src.add(2); src.add(7); src.add(3); src.add(2201); src.add(-21); dest.add(10); while (src.size() != 0) { for (ListIterator<Integer> li = dest.listIterator(); li.hasNext() ;) { int min = Collections.min(src); li.add(min); src.remove(min); } } } 

Note that dest should now be declared as List, not Collection, and you need to explicitly expand the for loop. However, I'm still not sure why you repeat dest in the first place. You add an element at each iteration so that you never reach the end.

What happened to this?

  while (src.size() != 0) { int min = Collections.min(src); dest.add(min); src.remove(min); } 

Or, as others have said, just call sort() - go to your custom Comparator if you need to.

+1
source

Honestly, I am not getting the for (int i : dest) . And if you delete it, there are actually no problems, and this answers the question :)

+1
source

As you saw, you cannot change a collection while you iterate over it. (To be more precise, you can change it, but you cannot continue the iteration)

You can either iterate over a copy of the list or use the traditional for loop.

In any case, make sure that you understand exactly what happens to the indices when the collection changes; otherwise your code will not work correctly.

For more specific tips, tell us what you are actually doing.

0
source

You can create temporary lists in which you keep track of what to add and remove without making any changes to dest and src. Then, outside the loop, use temporary lists to add and remove the necessary items. But, as John Skeet said, more specific requirements will help. I assume there are some limitations.

0
source

All Articles