-1

Is the following code safe? Assume its single-threaded.

for(String s : set){
    set.remove(s);
    set.remove(randomElementFromSet());
}

I'm pretty sure this should be fine, but I want to double check that I run no risk of iterating over an element that has already been removed.

Also if possible please provide reference so I can look it up next time.

David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122
  • 1
    No its not. You can use failsafe iterators for the same. Refer the [link](http://www.journaldev.com/378/how-to-avoid-concurrentmodificationexception-when-using-an-iterator) for more information – Vivek Singh Oct 24 '15 at 19:00
  • No, it probably throws ConcurrentModificationException. Use iterators as stated in last comment. – Forkmohit Oct 24 '15 at 19:02
  • Why don't you test it? With a standard HashSet or TreeSet, you'll get a ConcurrentModificationException, as documented. – JB Nizet Oct 24 '15 at 19:02
  • Did you create a test scenario and executed the code? That would've answered your question already. – Jeroen Vannevel Oct 24 '15 at 19:02

2 Answers2

1

Have you tried it? You would get ConcurrentModificationException.

One safe way to remove elements from a Collection while iterating over it is by using an Iterator explicitly:

for(Iterator<String> iter = set.iterator(); iter.hasNext();) {
    String s = iter.next();
    iter.remove();
}
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
Eran
  • 387,369
  • 54
  • 702
  • 768
1

You should not filter a collection using a for-each loop as you can get a ConcurrentModificationException.

To do it correctly you can use an Iterator, or removeIf. Both of these pieces of code print [Foo].

Approach using Iterator:

Set<String> set = new HashSet<String>(Arrays.asList("Foo", "Bar", "Baz"));
for (Iterator<String> i = set.iterator(); i.hasNext();)
    if (i.next().contains("B"))
        i.remove();
System.out.println(set);

Approach using removeIf (Java 8):

Set<String> set = new HashSet<>(Arrays.asList("Foo", "Bar", "Baz"));
set.removeIf(str -> str.contains("B"));
System.out.println(set);
Paul Boddington
  • 37,127
  • 10
  • 65
  • 116