3

I tried running the for-loop, but it would not run since allWords was empty. Therefore I added the first if-statement, so allWorlds would have atleast one item, and therefor the loop would run. The loop now runs, but I get:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)

A few google searches told me that this happens because I try to change the ArrayList while its in use (?). I wonder if there is an easy fix, or if I have to rewrite the code. Thanks in advance.

The code:

private void addWord(String word){

    if(allWords.isEmpty()){  //allWords defined above.
        allWords.add(word);
    }

    for (String check : allWords){

        if (!check.equalsIgnoreCase(word)){
            allWords.add(word);
        }
        else if(check.equalsIgnoreCase(word)){
            System.out.println("This word is a duplicate.");
        }
        else{
            System.out.println("Something went wrong.");
        }
    }
}
  • As suggested in the comments to your [earlier question](http://stackoverflow.com/questions/33109742/check-through-an-arraylist-if-it-contains-a-string-if-it-doesnt-add-that-stri), use a `Set` instead of a `List` if you do not want to allow duplicates in `allWords`. The return value of [`Set.add()`](https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#add%28E%29) indicates whether the set already contained the value or not. – Mick Mnemonic Oct 13 '15 at 21:46
  • Declaring `SortedSet allWords = new TreeSet(String.CASE_INSENSITIVE_ORDER);` will reduce your method into `if(!allWords.add(word)){System.out.println("This word is a duplicate.");}` – Mick Mnemonic Oct 13 '15 at 21:50

2 Answers2

1

You're stepping through the items in your for loop - what happens when you add something to the list while you're doing that? Java doesn't know how to handle that, so it throws a ConcurrentModificationException exception.

The solution? Don't mess with the array while you're using it in the for loop.

One solution (and this is not the only one) is to create a second array to hold the items you want to add temporarily while you're running through the for loop, then go back and add those items when you're done.

However, I suspect you have an error in your logic in the code fragment above. The way it's written, it looks like word should be added multiple times. I think what you want is a boolean flag:

  • set a flag to false before you start your for loop
  • if you find word while you're iterating over your array of words, then set it to true and exit the for loop
  • once you're done with the for loop, check your flag; if it's false, then add your word (since you didn't find it in the array).

Also, the if...else if...else is redundant: equalsIgnoreCase can only return true or false, so there's no third alternative and the else will never be hit.

Kryten
  • 15,230
  • 6
  • 45
  • 68
1

Your ArrayList is in use because you are iterating over it. I would recomend you to make a second list for temporal data

so basically something like this:

List<String> tempList = new ArrayList<String>();
.....
if (!check.equalsIgnoreCase(word)){
    tempList.add(word);
}
.....
Jürgen K.
  • 3,427
  • 9
  • 30
  • 66