NeroTheHero
NeroTheHero

Reputation: 3

Java - ConcurrentModificationException with recursive method and nested iterators

I have an assignment to write a Java program that will read in a context-free grammar and return the FirstSets of all non-terminals. I've taken a recursive approach with my FirstSet() method:

public static ArrayList<String> firstSet(String nonTerminal){
    ArrayList<String> first = new ArrayList<String>();
    //Find initial elements of FirstSet
    for(String[] current : prodRules) {
        if (current[0].equals(nonTerminal)){ //if the production rule is for that non-terminal
            if(current.length > 2) {
                first.add(current[2]);          //first element after "-->" is added to FirstSet
            } else
                first.add("eps");
        }
    }
    //Add the FirstSet of each element in the initial FirstSet
    ArrayList<String> copy = first; //to avoid ConcurrentModificationException
    Iterator<String> it1 = copy.iterator();
    while(it1.hasNext()) { //recursively find each FirstSet of the initial elements
        String s = it1.next();
        System.out.println("FIRST("+s+")={");
        ArrayList<String> nestedFS = firstSet(s);
        Iterator<String> it2 = nestedFS.iterator();
        while(it2.hasNext()) {
            String f = it2.next();
            if(!first.contains(f))
                first.add(f);
            System.out.print(" "+f+" ");
        }
        System.out.print("}");
    }
    return first;
}

However, I keep getting a ConcurrentModificationException error for the lines:

String s = it1.next();

ArrayList<String> nestedFS = firstSet(s);

As far as I can tell, I'm not modifying any lists that I am currently iterating through. Rather, I am iterating through copies. I'm not concerned with redundant memory usage or speed, I just need this to work.

Any clue as to what I'm doing wrong here? Any help is much appreciated.

Upvotes: 0

Views: 222

Answers (1)

Kamal Chanda
Kamal Chanda

Reputation: 173

Create the copy of ArrayList first using CopyOnWriteArrayList which avoids the ConcurrentModificationException.

    ArrayList<String> copy = first; //replace this line with 
    CopyOnWriteArrayList<String> copy= new CopyOnWriteArrayList<String>(first);

ArrayList is not threadsafe and need to implement the thread safety, instead, we can use CopyOnWriteArrayList which is thread safe.

Upvotes: 1

Related Questions