java - Java : Encountering ConcurrentModificationException. There's something wrong with my iterators and/or HashMaps, and I don't know what it is

标签 java compiler-errors java.util.scanner filenotfoundexception

我正在创建一个程序,该程序需要两个.txt文件,并打印出两个文本中出现的单词以及每个文本中每个共享单词出现的次数。我声明了两个具有有效路径的文件对象。但是,当我尝试创建使用两个.txt文件的两个Scanner对象时,对于声明新Scanner对象的两行代码,我都收到FileNotFoundException编译器错误。

仅供引用,我在while循环中使用了scannerObject.hasNext(),它将来自scannerObject.Next()的每个单词添加为值为1的HashMap变量中的新关键字,或者,如果该单词已经是HashMap中的关键字,则增加值(出现次数)减1。

我尝试用文件路径运行以下内容,并且以下简单程序运行无错误,并输出“It work!Hehehe”:

import java.io.*;
import java.util.*;

public class readingFilesPractice {
    public static void main(String[] args) {
        try{
            File x = new File("C:\\Users\\aravd.000\\Desktop\\Book1.txt");
            Scanner sc = new Scanner(x);
            while(sc.hasNext()){
                System.out.println(sc.next());
            }
            sc.close();
            System.out.println("It worked! Hehehe");
        }
        catch (Exception e){
            System.out.println("Error!");
        }
    }
}

顺便说一句,.txt文件具有连续多个空格和类似“1”之类的区域。

下面的代码遇到了两个FileNotFoundExceptions(没有try和catch块),在Visual Studio中,new Scanner(book1)new Scanner(book2)带有一条红色的蠕变线,当我将鼠标悬停在其上时,状态为“未处理的异常类型FileNotFoundExceptionJava(16777384)”。我的完整代码供引用,如下所示。
import java.io.*;
import java.util.*;

public class program1 {
    public static void main(String[] args) {
        try {
            File book1 = new File("C:\\Users\\aravd.000\\Desktop\\Book1.txt");
            File book2 = new File("C:\\Users\\aravd.000\\Desktop\\Book2.txt");


            // Counting the number of occurences of each word in book1
            Scanner readBook1 = new Scanner(book1);
            HashMap<String, Integer> wordsInBook1 = new HashMap<String, Integer>();
            while (readBook1.hasNext()) {
                String word = readBook1.next();
                if (wordsInBook1.containsKey(word)) {
                    int occurences = wordsInBook1.get(word) + 1;
                    wordsInBook1.put(word, occurences);
                } else {
                    wordsInBook1.put(word, 1);
                }
            }
            readBook1.close();

            // Counting the number of occurences of each word in book2
            Scanner readBook2 = new Scanner(book2);
            HashMap<String, Integer> wordsInBook2 = new HashMap<String, Integer>();
            while (readBook2.hasNext()) {
                String word = readBook2.next();
                if (wordsInBook2.containsKey(word)) {
                    int occurences = wordsInBook2.get(word) + 1;
                    wordsInBook2.put(word, occurences);
                } else {
                    wordsInBook2.put(word, 1);
                }
            }
            readBook2.close();

            // Creating two iterators for each HashMap
            Iterator wordsInB1Iter = wordsInBook1.entrySet().iterator();
            Iterator wordsInB2Iter = wordsInBook2.entrySet().iterator();

            // Running the wordsInB1Iter iterator to find and delete unique keys in
            // wordsInBook1
            while (wordsInB1Iter.hasNext()) {
                Map.Entry pair = (Map.Entry) wordsInB1Iter.next();
                if (!wordsInBook2.containsKey(pair.getKey())) {
                    wordsInBook1.remove(pair.getKey());
                }
            }

            // Running the wordsInB2Iter iterator to find and delete unique keys
            while (wordsInB2Iter.hasNext()) {
                Map.Entry pair = (Map.Entry) wordsInB2Iter.next();
                if (!wordsInBook1.containsKey(pair.getKey())) {
                    wordsInBook2.remove(pair.getKey());
                }
            }
            System.out.println(wordsInBook1);
            System.out.println(wordsInBook2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如果代码的其他部分坏了,我将不知道,因为我还没有调试它。如果您在其他地方发现错误,请告诉我。感谢您的努力,如果还有任何需要进一步说明的地方,请告诉我!

更新:当我将catch块更改为Exception e并使用e.printStackTrace时,我的代码输出以下内容:
java.util.ConcurrentModificationException
        at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
        at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1526)
        at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1524)
        at prorgam1.main(program1.java:50)

Link to error descriptions within the "PROBLEMS" tab in VisualStudios

上图可能提供有关我的迭代器和HashMaps问题的更多详细信息。

最佳答案

答案与@Pedro Borges相同,但

  • 请使用泛型!您的代码充满了强制转换,但不应该。
  • 使用Iterator.remove()删除当前值,而不使用源集合。这就是您获取ConcurrentModificationException的原因。
  • 如果不需要Map.Entry,则可以改用keySet()
  • 您正在使用Java>8。如果是Java 11,则也可以使用var

  • 您的代码:
            Iterator<Map.Entry<String, Integer>>> wordsInB1Iter = wordsInBook1.entrySet().iterator();
            Iterator<Map.Entry<String, Integer>>> wordsInB2Iter = wordsInBook2.entrySet().iterator();
    
            // Running the wordsInB1Iter iterator to find and delete unique keys in
            // wordsInBook1
            while (wordsInB1Iter.hasNext()) {
                Map.Entry<String,Integer> pair = wordsInB1Iter.next();
                if (!wordsInBook2.containsKey(pair.getKey())) {
                    wordsInB1Iter.remove();
                }
            }
    
            // Running the wordsInB2Iter iterator to find and delete unique keys
            while (wordsInB2Iter.hasNext()) {
                Map.Entry<String,Integer> pair = wordsInB2Iter.next();
                if (!wordsInBook1.containsKey(pair.getKey())) {
                    wordsInB2Iter.remove();
                }
            }
    

    而且,在我使用它的同时,您还可以考虑重构阅读单词的方式:
  • 通过使用一种方法而不是复制代码
  • 通过尝试使用资源(Java 7++)
  • 使用Map.merge(Java 8++)

  • 如:
    void words(File file) {
      try (Scanner scanner = new Scanner(file)) {
        var result = new HashMap<String,Integer>();
        while (scanner.hasNext()) {
          var word = scanner.next();
          result.merge(word, 1, Integer::sum); // or (a, b) -> a + b
        }
        return result;
      }
    }
    

    您可能(应该?)使用MutableInteger(来自common-lang3),以避免由于性能原因而从Integer取消装箱到int

    关于java - Java : Encountering ConcurrentModificationException. There's something wrong with my iterators and/or HashMaps, and I don't know what it is,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60984188/

    相关文章:

    java - Android RenderScript FinalizerWatchdogDaemon 致命异常

    java - 参数化类中的空构造函数

    java - 与 JavaVM Framework 链接的 OS X 应用程序能否与 Oracle 的 JRE 1.7 一起运行?

    java - 检查控制台-计算机或程序错误?

    java - 使用scanner.nextLine()

    java - 访问 spring 上下文

    java - 字符串预期错误?

    c# - ObservableCollection w/.net 4.0

    java - 构造 java.util.Scanner 的意外行为

    java - Scanner nextInt() 不返回字符串中的所有整数?