简体   繁体   English

我无法弄清楚为什么会出现此错误:ConcurrentModificationException

[英]I cannot figure out why I have this error: ConcurrentModificationException

I'm writing a program that's made to solve the Mastermind game. 我正在编写一个解决Mastermind游戏的程序。 The gist of the program is to take a list of all the possible solutions and after every guess that isn't the correct one, remove anything from the list that wouldn't at least give that solution. 该程序的要旨是列出所有可能的解决方案,并在每一次都不正确的猜测之后,从列表中删除至少不会给出该解决方案的任何内容。 This method is made to compare two Strings (guess and strFromArray) to see if they get the same values. 使用此方法来比较两个字符串(guess和strFromArray)以查看它们是否获得相同的值。 However, I'm getting an error and I can't figure out why. 但是,我遇到了一个错误,我不知道为什么。 Any help would be appreciated. 任何帮助,将不胜感激。

    Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at Game.shortenTheList(Game.java:88)
at Game.guess(Game.java:76)
at Game.play(Game.java:40)
at Game.main(Game.java:23)


/*
 * Compares the two strings. If they would get the same output, return false. If they would get a different output, return true.
 */
public boolean compare(String guess, String strFromArray, int black, int white)
{
    int white2 = 0;
    int black2 = 0;

    char[] arr1 = guess.toCharArray();
    char[] arr2 = strFromArray.toCharArray();

    for(int i=0; i<guess.length(); i++)
    {
        if(arr1[i] == arr2[i])
        {
            black2 ++;
            arr1[i] = '$';
            arr2[i] = '%';
        }
    }

    for(int i=0; i<guess.length(); i++)
    {
        for(int j=0; j<strFromArray.length(); j++)
        {
            if(arr1[i] == arr2[j])
            {
                white2++;
                arr1[i] = '!';
                arr2[j] = '@';
            }
        }
    }

    if(black == black2 && white == white2)
        return false;

    else
        return true;
}

/*
 * Shortens the list of possible solutions by eliminating everything that wouldn't get at least the given output.
 */
public void shortenTheList(String guess, int black1, int white1)
{
    for (String str : possibleSolutions)
    {
        if(compare(guess, str, black1, white1))
        {
            possibleSolutions.remove(str);
        }
    }
}

Once you open an Iterator (which you do implicitly when using for(String str: possibleSolutions) , any modifications to the underlying collection ( possibleSolutions ) except by calling remove on the Iterator will cause a ConcurrentModificationException ; this is very clearly documented on the collection classes. 一旦打开了Iterator (在使用for(String str: possibleSolutions) PossibleSolutions时隐式地进行for(String str: possibleSolutions) ,对基础集合( possibleSolutions )的任何修改(除非通过在Iterator上调用remove )都将导致ConcurrentModificationException ;这在集合类中非常清楚地记录了下来。 。

If you need to remove items from the collection, use an explicit Iterator : 如果您需要从集合中删除项目,请使用显式的Iterator

Iterator<String> it = possibleSolutions.iterator();
while(it.hasNext()) {
    if(compare(guess, it.next(), black1, white1))
        it.remove();
}

As @allprog pointed out, a functional approach is better when you have such a clear "filtering" problem. 正如@allprog指出的那样,当您遇到如此明显的“过滤”问题时,功能性方法会更好。 Until Java 8 is an option, using Guava's Iterables#filter or Iterables#removeIf is probably a good choice; 在选择Java 8之前,使用Guava的Iterables#filterIterables#removeIf可能是一个不错的选择。 you would just wrap your compare method and pass it in. 您只需包装您的compare方法并将其传递。

/*
 * Shortens the list of possible solutions by eliminating everything that wouldn't get at least the given output.
 */
public void shortenTheList(String guess, int black1, int white1)
{
    for (String str : possibleSolutions)
    {
        if(compare(guess, str, black1, white1))
        {
            possibleSolutions.remove(str);
        }
    }
}

There's your problem. 有你的问题。

Instead, use: 而是使用:

/*
 * Shortens the list of possible solutions by eliminating everything that wouldn't get at least the given output.
 */
public void shortenTheList(String guess, int black1, int white1)
{
    Iterator<String> it = possibleSolutions.iterator();
    while(it.hasNext())
    {
        String str = it.next();
        if(compare(guess, str, black1, white1))
        {
            it.remove();
        }
    }
}

This is the only clean way to remove an object from a collection you're currently iterating over. 这是从当前正在迭代的集合中删除对象的唯一干净方法。 The other, less elegant way would be to create a separate list of String s to remove and iterate over that. 另一种不太优雅的方法是创建一个单独的String列表以删除并对其进行迭代。

You cannot modify the list possibleSolutions while you are iterating through it using a foreach loop. 当您使用foreach循环遍历列表时,您将无法修改possibleSolutions列表。

Change your code to something like this: 将您的代码更改为如下所示:

public void shortenTheList(String guess, int black1, int white1)
{    
    for(Iterator<String> it = possibleSolutions.iterator(); it.hasNext()){
        String str = it.next();
        if(compare(guess, str, black1, white1)){
            it.remove();
        }
    }
}

Like chrylis says, you can't remove an element from a collection without using an Iterator. 就像chrylis所说的那样,如果不使用Iterator,就无法从集合中删除元素。

example: 例:

public void shortenTheList(String guess, int black1, int white1)
{
for (String str : possibleSolutions)
{
if(compare(guess, str, black1, white1))
{
possibleSolutions.remove(str);
}
}
}

should be: 应该:

public void shortenTheList(String guess, int black1, int white1)
{
Iterator i = possibleSolutions.Iterator();
while(i.hasNext())
{
String str = (String) i.next();
if(compare(guess, str, black1, white1))
{
i.remove();
}
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法弄清楚为什么会引发ConcurrentModificationException - Cannot figure out why it throws ConcurrentModificationException 我无法弄清楚这个ConcurrentModificationException - I can't figure out this ConcurrentModificationException 输出错误,我无法弄清原因 - Incorrect Output and I cannot figure out why 我在 BlueJ 中无法弄清楚的编译错误 - A compiling Error I cannot figure out in BlueJ 我不断收到表达式错误代码的非法开头和“;” 预期的错误代码,我不知道为什么 - I keep getting illegal start of expression error codes and ';' expected error codes and I cannot figure out why 我在这里收到“不兼容的类型”错误,我不知道为什么 - I am getting an “incompatible types” error right here and I cannot figure out why 我无法弄清楚 getTotalFlightTime() - I cannot figure out getTotalFlightTime() 无法弄清楚为什么我不断收到找不到符号编译错误 - Can't figure out why i keep getting cannot find symbol compile error 由于数据类型中的某些错误,我的构造函数无法正常工作,我无法弄清为什么 - My constructor is not working as expected due to some error in data types and I cannot figure out why 我收到一个错误:“异常 FileNotFoundException 永远不会在相应的 try 语句的主体中抛出”并且无法弄清楚原因 - I'm getting an error: “exception FileNotFoundException is never thrown in body of corresponding try statement” and cannot figure out why
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM