Question

I need some help with an iterator that it seems no matter what I do it keeps giving me the error:

Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
 at java.util.ArrayList$Itr.next(ArrayList.java:831)
 at package.Dictionary.writer(Dictionary.java:72)
 at package.main.main(main.java:24) <5 internal calls>

I could use any help given to help solve this, I am somewhat new to Java programming. My full code is below:

package package;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class Dictionary {
    Collection<String> webster = new ArrayList<String>();
    Iterator<String> iter = webster.iterator();
    File path = null;

    public Dictionary(Collection<String> words) {
        if (words == null) {
            throw new NullPointerException("Error: Collection NULL");
        } else {
            if (!words.isEmpty()) {
                clear();
            }
        }
    }

    public long load(File file) throws FileNotFoundException {
        String filePath = file.getAbsolutePath();
        if (file.getAbsolutePath().equals(null)
                || file.getAbsolutePath().equals("")) {
            throw new FileNotFoundException("Error: No File Found!");
        } else {
            if (file.exists()) {
                Scanner fileScanner = new Scanner(new File(filePath));
                long time = System.nanoTime();
                while (fileScanner.hasNext()) {
                    webster.add(fileScanner.next());
                }
                long time2 = System.nanoTime();
                long duration = time2 - time;
                return duration;
            } else {
                throw new FileNotFoundException("Error: No File Exsists!");
            }
        }
    }

    public boolean contains(String target) {
        if (webster.contains(target)) {
            return true;
        } else {
            return false;
        }
    }

    public void clear() {
        webster.clear();
    }

    public void writer() throws Exception {
        PrintWriter out = new PrintWriter("words.txt");
        while (iter.hasNext()) {
            out.println(iter.next());
        }
        out.close();
    }
}
Was it helpful?

Solution

The issue you are having now is because you are creating the iterator, then modifying the list by loading the dictionary, then using the iterator (which now throws the exception because the list was modified after the iterator was created).

You have your Iterator as an instance variable and you are instantiating it on initialization. You don't want to do this here. Instead, create the Iterator in the method you are using it in, e.g. get rid of the instance variable and do:

public void writer() throws Exception {
    PrintWriter out = new PrintWriter("words.txt");
    Iterator<String> iter = webster.iterator();
    while (iter.hasNext()) {
        out.println(iter.next());
    }
    out.close();
}

Or, even clearer, and without the use of an explicit Iterator, simply do:

public void writer() throws Exception {
    PrintWriter out = new PrintWriter("words.txt");
    for (String entry : webster)
        out.println(entry);
    out.close();
}

An iterator is just a temporary object that can be used for iterating over a collection of items, it does not need to stick around. Create one when you need it, then forget about it when you're done with it.

OTHER TIPS

You are modifying the Collection named webster after the Iterator is created but before it is finished iterating. That causes the ConcurrentModificationException.

Considering that you don't need to iterate until you're in writer, just create a local Iterator there, so it won't be there to detect a modification.

PrintWriter out = new PrintWriter("words.txt");
Iterator<String> iter = webster.iterator();
while (iter.hasNext()) {
    out.println(iter.next());
}
out.close();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top