Monday, January 6, 2014

How to Remove Objects from Collection or ArrayList in Java while Traversing - Iterator remove() method Example

How do you remove objects from Java collections like ArrayList, while iterating is one of the frequent questions my reader asked to me in my post about Top 25 Java Collection Interview Questions. Well, this question may seems quite easy, because every java.util.Collection implementation e.g. List or Set has remove() method to delete a particular object, which can be used to remove elements from any Collection e.g. ArrayList, LinkedList or Vector. Well, this is where things goes wrong and interviewers are interested to see, whether you can point about remove() method from Iterator or not. Answer of this question is as simple as that, you should be using Iterator's remove() method to delete any object from Collection you are iterating, but this is not the end of this question. Most likely you will be asked to explain, what is difference in removing object using remove() method of Collection over remove() method of Iterator and why one should use over other? Reason is ConcurrentModificationException, if you use remove() method of List, Set or basically from any Collection to delete object while iterating, it will throw ConcurrentModificationException. Though remove() method of java.util.Collection works fine to remove individual object, they don't work well, when you are iterating over collection.  Let's see a code example to clear doubts




How to Remove elements From ArrayList while Iterating

Java Tips to remove objects from ArrayList while iteratingIn below code, we have a list of exchanges and we are removing exchanges which are closed at the moment. Code is as simple as it could be and it's hard to find anything wrong on it by just looking, but things will be different when you run it. You will be hit by ConcurrentModificationException, as soon as you run, because here are we are using remove() method of ArrayList to remove objects, instead of Iterator's remove method. In order to fix ConcurrentModificationException, just use remove() method of java.util.Iteator class.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
  * Java program to demonstrate how to remove object form List and differnece
  * between Iterator's remove() method and Colection's remove() method in Java
  *
 */
public class ObjectRemovalTest {
  
    public static void main(String args[]) {
      
       List markets = new ArrayList();
     
       StockExchange TSE = new StockExchange(){
         
            @Override
            public boolean isClosed() {
                return true;
            }         
       };
     
       StockExchange HKSE = new StockExchange(){

            @Override
            public boolean isClosed() {
                return true;
            }         
       };
      
       StockExchange NYSE = new StockExchange(){

            @Override
            public boolean isClosed() {
                return false;
            }         
       };
      
       markets.add(TSE);
       markets.add(HKSE);
       markets.add(NYSE);
     
     
       Iterator itr = markets.iterator();
     
       while(itr.hasNext()){
           StockExchange exchange = itr.next();
           if(exchange.isClosed()){
               markets.remove(exchange); //Use itr.remove() method
           }
       }
           
    }    
  
}

interface StockExchange{
    public boolean isClosed();
}

Output
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at ObjectRemovalTest.main(StringReplace.java:63)
Java Result: 1

to be frank, even with the use of modern IDE like Eclipse, you may code it wrong, and end up confusing yourself when you see ConcurrentModificationException, because that sometime mislead programmers. It looks that may be another thread is modifying collection, and with this thought you won't look the code you are using for traversing ArrayList. That's why sometime interviewer present code and ask you to find bugs on it, or they may simply ask you to write code for removing objects from Collection while traversing over them. Always remember to use Iterator's remove() method for removing objects from Collection in Java.


1 comment :

Haifeng Zhang said...

good article, thanks! One typo is itr.next() has to be casting to StockExchange in the while loop.

Post a Comment