1

I'm doing a library system on Java. I have a class called Things with two children: Print and Digital. Print is then divided into Book and Periodical.

The following is a snippet of the code I wrote to print items. The full code has imports.

public class Collection
{
    private ArrayList <Things> theCollection;
    private ListIterator <Things> listItr;

    public Collection ()
    {
        theCollection = new ArrayList <> ();
        listItr = theCollection.listIterator ();
    }

    public void get ()
    {
        Things sThing;
        Book sBook;
        Periodical sPeriodical;
        Digital sDigital;

        sThing = listItr.next ();
        if (sThing instanceof Book)
        {
            sBook = (Book) sThing;
            sBook.bookInfo ();
        }
        else if (sThing instanceof Periodical)
        {
            sPeriodical = (Periodical) sThing;
            sPeriodical.periodicalInfo ();
        }
        else if (sThing instanceof Digital)
        {
            sDigital = (Digital) sThing;
            sDigital.digitalInfo ();
        }
    }

    public void printAll ()
    {
        while (listItr.hasNext ())
            get ();
    }
}

I have a problem on the following statement in the get() method:

sThing = listItr.next ();

When I ran the code, it gave me a ConcurrentModificationException. I tried to search for answers online, but all of them suggested to use an iterator, and I have that. Where did I do wrong?

Thanks for your help.

2 Answers2

4

The problem

You create/request an iterator while constructing your class, directly after creating the list. At this point the list will be empty.

I assume that you afterwards add/remove elements to/from that list. This is a concurrent modification because the iterator constrains the iteration to happen on an unmodified list after its creation. The next call to the iterator will then throw this exception.

The solution

Don't create the iterator in the constructor of your class. Create it at the needed time:

public class Collection {
    private ArrayList <Things> theCollection;

    public Collection () {
        theCollection = new ArrayList <> ();
    }

    public void get () {
        ...
        ListIterator <Things> listItr = theCollection.listIterator();
        sThing = listItr.next ();
        ...
    }
}
Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
3

the problem lies in the constructor:

public Collection ()
{
    theCollection = new ArrayList <> ();
    listItr = theCollection.listIterator ();
}

you are creating a ListIterator before adding elements to the list; in order to avoid the error you must create the iterator just before iterating over the elements; so remove the iterator creation in the conustructor and place in just before you need it; see here and here for similar questions.

Community
  • 1
  • 1
Giovanni
  • 3,951
  • 2
  • 24
  • 30