Ahsan Rafiq
Ahsan Rafiq

Reputation: 111

Use of the Iterator class in Java

I am trying to use Iterator but it gives me this error:

java.util.concurrentModificationException: null (in java.util.ArrayList$Itr)

The code is here:

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

public class Iteratorr
{    
  ArrayList<String> list = new ArrayList<>();
  Iterator<String> it = list.iterator();

  void add()
  {
    list.add("Hello");
    list.add("I");
    list.add("am");
    list.add("ArrayList");
  }

  void print()
  {   
    while(it.hasNext()) 
    {
      String str = it.next();
      System.out.println(str);
    }
  }      
}

Can anyone explain the reason?

Upvotes: 1

Views: 208

Answers (3)

Willi Mentzel
Willi Mentzel

Reputation: 29924

You have to retrieve the iterator after you made the last changes to your List! Otherwise it will be a different iterator that doesn't "know" the new List's contents.

A more elegant way utilizing the (default) iterator implicitely:

void print()
{   
    for(String str : list) 
    {
        System.out.println(str);
    }
}

Although this might be better for understanding, especially if you want to define your own Iterator later on:

void print()
{   
    Iterator<String> it = list.iterator();

    while(it.hasNext()) 
    {
        System.out.println(it.next());
    }
} 

Upvotes: 2

NPE
NPE

Reputation: 500953

The sequence of events is as follows:

  1. You create an iterator for the (empty) list.
  2. You add elements to the list.
  3. You start using the iterator created in step 1.

This won't work because step 2 has invalidated the iterator. This is what the exception is telling you. From the Javadoc:

The iterators returned by [ArrayList's] iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

You need to create the iterator just before you start iterating:

public class Iteratorr
{    
  ...
  Iterator<String> it = null;

  void print() {
    it = list.iterator();
    while(it.hasNext()) {
      String str = it.next();
      System.out.println(str);
    }
  }      

(An even better way would be to declare it inside print rather than as a member of the class.)

These days the idiomatic way to write such loops is

  void print() {
    for (String str : list) {
      System.out.println(str);
    }
  }      

It has the same effect as using an explicit iterator, but is much easier on the eye.

Upvotes: 3

Diego Montoya
Diego Montoya

Reputation: 139

that Excpption depends on how you are calling the method. You could use the variables locally in the method as follows.

void print()
{   
    ArrayList<String> list = new ArrayList<>();

    //Add elements here
    add(list);

    Iterator<String> it = list.iterator();

    while(it.hasNext()) {

        String str = it.next();

        System.out.println(str);
    }

}

void add( List list)
    {
        list.add("Hello");
        list.add("I");
        list.add("am");
        list.add("ArrayList");
    }

Upvotes: 0

Related Questions