ArrayList上的java.util.ConcurrentModificationException

ArrayList上的java.util.ConcurrentModificationException,java,arraylist,netbeans,Java,Arraylist,Netbeans,下面的代码搜索给定用户输入的文件,如果存在匹配项,则匹配项上的行将添加到ArrayList 我似乎对ArrayList有问题,因为我在ArrayList上得到了java.util.ConcurrentModificationException 这个问题以前已经回答过了,但我仍然不明白代码中的什么问题导致了这个问题 任何帮助都将不胜感激 import java.io.File; import java.io.FileNotFoundException; import java.util.Array

下面的代码搜索给定用户输入的文件,如果存在匹配项,则匹配项上的行将添加到ArrayList

我似乎对ArrayList有问题,因为我在ArrayList上得到了java.util.ConcurrentModificationException

这个问题以前已经回答过了,但我仍然不明白代码中的什么问题导致了这个问题

任何帮助都将不胜感激

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;


public class Test {

    public static void main(String[] args)
    {
        String givenAccnt;

        Scanner scan = new Scanner(System.in);
        System.out.println("Enter an account...");
        givenAccnt = scan.nextLine();
        findPasswords(givenAccnt);
    } 

    private static void findPasswords(String userInput)
    {
        File file = new File("C:\\Users\\Nuno\\Documents\\my_passwords.txt");   //file to search
        Scanner scan = new Scanner(System.in);                                  //Scanner object to get user input
        String accntToken;                                                      //first string token of a line, i.e. "account"
        String getLine;                                                         //this is the line that contains the password the user is looking for. There may be +1 lines thus I have to return them all.*** must use ArrayList of strings (lines of strings) instead of Array
        ArrayList<String> collectedLines = new ArrayList<>();                   //any matched line(s) is collected to an ArrayList of strings (lines)
        ListIterator<String> outputMatches =  collectedLines.listIterator();    //iterator for ArrayList... used to iterate and display collected lines to output window
        String nextOutput;                                                      //line(s) that was collected from ArrayList
        boolean isFound = false;
        int i;                                                                  //delineator... finds index of 1st space " " on that line  (or try ' '), so we can get to the 1st token of a line i.e. "account"
        int v = 0;                                                              //counter... everytime an input is matched to a line, the line is collected to ArrayList... increas    e v... the pane will also display number of accounts found (i.e. v)

        try
        {   
            Scanner scanFile = new Scanner(file);                               //Scanner object to scan file
            while(scanFile.hasNextLine())                                       //Scanner scans file... until end of file
            {
                getLine = scanFile.nextLine();                                  //gets a line
                i = getLine.indexOf(" ");                                       //get index of substring (account) token
                accntToken = getLine.substring(0, i);                           //gets the account (1st string token in the line, after " ")                        
                if(userInput.equalsIgnoreCase(accntToken))                      //if given input account equals the account on the line 
                {     
                    collectedLines.add(getLine);                                //append the line to the ArrayList collectedLines
                    isFound = true;                                             //flag
                    v++;                              //increment number of matches found
                }
            }
            System.out.println(v + " matches were found and added to the ArrayList!"); //tests to see search algorithm is working
            while(outputMatches.hasNext())                                      //loop iterates the ArrayList to write collectedLines to the dialog
            {
                nextOutput = (String)outputMatches.next();                      //get line(s) from the ArrayList

                if(!isFound)
                {
                } else 
                    {
                        System.out.println("Passwords found: " +nextOutput);
                        outputMatches.remove();
                    }
            }                  
        }catch (FileNotFoundException ex) 
        {
            Logger.getLogger(PassLock_Main.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Error processing file!");
        }
    }
}
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.util.ArrayList;
导入java.util.ListIterator;
导入java.util.Scanner;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.JOptionPane;
公开课考试{
公共静态void main(字符串[]args)
{
字符串给定CNT;
扫描仪扫描=新扫描仪(System.in);
System.out.println(“输入帐户…”);
givenacnt=scan.nextLine();
查找密码(givenacnt);
} 
私有静态void findPasswords(字符串userInput)
{
File File=new File(“C:\\Users\\Nuno\\Documents\\my_passwords.txt”);//要搜索的文件
Scanner scan=new Scanner(System.in);//获取用户输入的Scanner对象
String accntToken;//行的第一个字符串标记,即“account”
String getLine;//这是包含用户正在查找的密码的行。可能有+1行,因此我必须全部返回。***必须使用ArrayList of String(lines of String)而不是Array
ArrayList collectedLines=new ArrayList();//将所有匹配的行收集到字符串(行)的ArrayList中
ListIterator outputMatches=collectedLines.ListIterator();//ArrayList的迭代器…用于迭代收集的行并将其显示到输出窗口
字符串nextOutput;//从ArrayList收集的行
布尔值isFound=false;
int i;//描绘器……在该行上查找第一个空格“”的索引(或尝试“”),因此我们可以找到该行的第一个标记,即“account”
int v=0;//计数器…每次输入与一行匹配时,该行都会被收集到ArrayList…增加EV…窗格还将显示找到的帐户数(即v)
尝试
{   
Scanner scanFile=新扫描仪(文件);//要扫描文件的扫描仪对象
while(scanFile.hasNextLine())//扫描仪扫描文件…直到文件结束
{
getLine=scanFile.nextLine();//获取一行
i=getLine.indexOf(“”;//获取子字符串(帐户)令牌的索引
accntToken=getLine.substring(0,i);//获取帐户(行中第一个字符串标记,在“”之后)
if(userInput.equalsIgnoreCase(accntToken))//如果给定的输入帐户等于行上的帐户
{     
collectedLines.add(getLine);//将该行附加到ArrayList collectedLines
isFound=true;//标志
v++;//找到的匹配项的增量
}
}
System.out.println(v+“已找到匹配项并将其添加到ArrayList!”);//测试以查看搜索算法是否正常工作
while(outputMatches.hasNext())//循环迭代ArrayList以将收集的行写入对话框
{
nextOutput=(字符串)outputMatches.next();//从ArrayList获取行
如果(!isFound)
{
}否则
{
System.out.println(“找到的密码:+nextOutput”);
outputMatches.remove();
}
}                  
}捕获(FileNotFoundException ex)
{
Logger.getLogger(PassLock_Main.class.getName()).log(Level.SEVERE,null,ex);
System.out.println(“错误处理文件!”);
}
}
}

执行以下操作时会出现问题:

  • ArrayList
  • 修改
    ArrayList
    (在您的示例中,您将
    添加()
  • 使用项目1中的迭代器
  • 您需要避免修改正在迭代的列表,或者使用一些支持并发修改+迭代的集合实现

    例如,您可以尝试改用
    CopyOnWriteArrayList
    ,但请注意,它会在每次修改列表时复制列表

    更新:在您的情况下,修改集合后只需获取迭代器。试着移动

    ListIterator<String> outputMatches =  collectedLines.listIterator();
    

    看起来您试图同时从两个不同的线程操作同一个arraylist。不行that@ja08prat我该如何解决这个问题?@codEinstein从一开始就设置一个断点,然后逐行检查,直到找到问题所在,但无法通过查看确定答案it@ja08prat您不需要多个线程来获取
    ConcurrentModificationException
    (正如所讨论的代码中有一个线程所证明的那样)。@Kayaman没错,我只是随地吐痰,如果我更确信这就是问题所在的话,我会将其作为答案发布的。太好了!现在我明白为什么了……我只是不太熟悉使用这种容器
    System.out.println(v + " matches were found and added to the ArrayList!");