簡體   English   中英

我無法弄清楚為什么會出現此錯誤:ConcurrentModificationException

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

我正在編寫一個解決Mastermind游戲的程序。 該程序的要旨是列出所有可能的解決方案,並在每一次都不正確的猜測之后,從列表中刪除至少不會給出該解決方案的任何內容。 使用此方法來比較兩個字符串(guess和strFromArray)以查看它們是否獲得相同的值。 但是,我遇到了一個錯誤,我不知道為什么。 任何幫助,將不勝感激。

    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);
        }
    }
}

一旦打開了Iterator (在使用for(String str: possibleSolutions) PossibleSolutions時隱式地進行for(String str: possibleSolutions) ,對基礎集合( possibleSolutions )的任何修改(除非通過在Iterator上調用remove )都將導致ConcurrentModificationException ;這在集合類中非常清楚地記錄了下來。 。

如果您需要從集合中刪除項目,請使用顯式的Iterator

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

正如@allprog指出的那樣,當您遇到如此明顯的“過濾”問題時,功能性方法會更好。 在選擇Java 8之前,使用Guava的Iterables#filterIterables#removeIf可能是一個不錯的選擇。 您只需包裝您的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);
        }
    }
}

有你的問題。

而是使用:

/*
 * 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();
        }
    }
}

這是從當前正在迭代的集合中刪除對象的唯一干凈方法。 另一種不太優雅的方法是創建一個單獨的String列表以刪除並對其進行迭代。

當您使用foreach循環遍歷列表時,您將無法修改possibleSolutions列表。

將您的代碼更改為如下所示:

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();
        }
    }
}

就像chrylis所說的那樣,如果不使用Iterator,就無法從集合中刪除元素。

例:

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

應該:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM