java.util.NoSuchElementException 来自扫描仪

java.util.NoSuchElementException from Scanner

我的扫描仪在读取文件时出现问题。假设在逗号后跟 space 或创建新行时创建一个新标记,但在 4 个标记之后,它会抛出 NoSuchElementException。

    private Map<String, Double> createElementMassMap(String filePath) {
    Map<String, Double> elementMap = new HashMap<>();
    try (Scanner sc = new Scanner(new FileReader(filePath))) {
        sc.useDelimiter(Pattern.compile("(, ) | (\r\n)"));
        sc.useLocale(Locale.US);
        while(sc.hasNext()) {
            String name = sc.next();
            System.out.println(name);
            double mass = sc.nextDouble();
            System.out.println(mass);
            elementMap.put(name, mass);
        }
    } catch (IOException e) {
        e.printStackTrace();
        JOptionPane.showMessageDialog(self, "Error loading ElementMasses file.", "IOException", JOptionPane.ERROR_MESSAGE);
    } 
    return elementMap;
}

这是它试图读取的文件

H, 1.00
O, 16.00

并且我确保文件中没有空行。

我在我的电脑上试过运行这段代码:

import javax.swing.JOptionPane;
import java.util.Scanner;
import java.util.Locale;
import java.util.regex.Pattern;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
import java.awt.Component;

public class Test {
    public static void main(String[] args) {
        createElementMassMap("file.txt");
    }

    private static Map<String, Double> createElementMassMap(String filePath) {
        Map<String, Double> elementMap = new HashMap<>();
        try (Scanner sc = new Scanner(new FileReader(filePath))) {
            sc.useDelimiter(Pattern.compile("(, ) | (\r\n) | (\n)"));
            sc.useLocale(Locale.US);
            while(sc.hasNext()) {
                String name = sc.next();
                System.out.println(name);
                System.out.println("hi");
                double mass = sc.nextDouble();
                System.out.println(mass);
                elementMap.put(name, mass);
            }
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog((Component)new Object(), "Error loading ElementMasses file.", "IOException", JOptionPane.ERROR_MESSAGE);
        }
        return elementMap;
    }
}

而我得到的是

H, 1.00
O, 16.00

hi
Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:862)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextDouble(Scanner.java:2413)
    at Test.createElementMassMap(Test.java:25)
    at Test.main(Test.java:13)

所以,看起来第一个匹配项匹配了整个文件。如果删除管道周围的空格:

import javax.swing.JOptionPane;
import java.util.Scanner;
import java.util.Locale;
import java.util.regex.Pattern;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
import java.awt.Component;

public class Test {
    public static void main(String[] args) {
        createElementMassMap("file.txt");
    }

        private static Map<String, Double> createElementMassMap(String filePath) {
            Map<String, Double> elementMap = new HashMap<>();
            try (Scanner sc = new Scanner(new FileReader(filePath))) {
                sc.useDelimiter(Pattern.compile("(, ) | (\r\n) | (\n)"));
                sc.useLocale(Locale.US);
                while(sc.hasNext()) {
                    String name = sc.next();
                    System.out.println(name);
                    System.out.println("hi");
                    double mass = sc.nextDouble();
                    System.out.println(mass);
                    elementMap.put(name, mass);
                }
            } catch (IOException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog((Component)new Object(), "Error loading ElementMasses file.", "IOException", JOptionPane.ERROR_MESSAGE);
            }
            return elementMap;
        }
    }

消息消失,完美运行

您使用的是什么平台?行分隔符因平台而异。使用它来支持两者(当然还要删除正则表达式中“|”周围的额外空格)。

            sc.useDelimiter("(, )|(\r\n)|(\n)");

嗯,我是个白痴,我的模式搞砸了。

//instead of 
sc.useDelimiter(Pattern.compile("(, ) | (\r\n)"));
//it should be this
sc.useDelimiter(Pattern.compile("(, )|(\r\n)"));

谢谢你们的有用回答!

我不喜欢扫描仪,尽量避免使用它。 如果您想尝试 bufferedReader,请按以下方法操作:

 BufferedReader in = new BufferedReader(new FileReader(filePath));
   StringTokenizer st;
   String line;

   try {
    while((line = in.readLine()) != null) {
           st = new StringTokenizer(line,", " );
           String name = st.nextToken();
           System.out.println(name);
           double mass = Double.parseDouble(st.nextToken());
           System.out.println(mass);
       }
} catch (Exception e) {
    // kaboom... something happened
    e.printStackTrace();
} 

编辑: 您可以调整 StringTokenizer 构造函数中的分隔符以满足您的需要