Wednesday, April 1, 2009

Remove Item From Collection

If you directly remove from an item from a collection you will trigger a java.util.ConcurrentModificationException

Collection<String> mySet = new HashSet<String>();
mySet.add("one");
mySet.add("two");
mySet.add("three");
mySet.add("four");

for (String item : mySet) {
  if (item.startsWith("t")) {
    mySet.remove(item);
  }
}

System.out.println(mySet);
Which will give this.

Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
 at java.util.HashMap$KeyIterator.next(Unknown Source)
For years, when I had a collection and I wanted to remove a number of items from it I used this pattern.

Collection<String> mySet = new HashSet<String>();
mySet.add("one");
mySet.add("two");
mySet.add("three");
mySet.add("four");

Collection<String> toBeRemoved = new HashSet<String>();

for (String item : mySet) {
  if (item.startsWith("t")) {
    toBeRemoved.add(item);
  }
}

mySet.removeAll(toBeRemoved);

System.out.println(mySet);
Which will give this.
[one, four]
I never really like this and today I bothered to look beyond my nose and found you can remove without the need for the toBeRemoved Collection by using an Iterator and its remove method.

  Collection<String> mySet = new HashSet<String>();
  mySet.add("one");
  mySet.add("two");
  mySet.add("three");
  mySet.add("four");

  Iterator<String> iterator = mySet.iterator();
    
  while(iterator.hasNext()) {
    String item = iterator.next();
    if (item.startsWith("t")) {
      iterator.remove();
    }
  }

  System.out.println(mySet);
This one I like, no need for that silly extra collection object.

0 comments:

Post a Comment