【问题标题】:Exception in thread "main" java.util.NoSuchElementException线程“主”java.util.NoSuchElementException 中的异常
【发布时间】:2013-03-02 04:16:33
【问题描述】:

每当我运行它时,chooseCave() 函数都可以与in.nextInt() 一起正常工作。当我选择洞穴时,消息以 2 秒的间隔弹出,然后一旦超过该部分,它就会给我错误:

Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Unknown Source)
    at Dragon.main(Dragon.java:81)

我已经尝试过hasNextLine()hasNextInt(),当我在main 方法中使用while hasNextLine() 时,我得到了更多的错误。当我在chooseCave() 方法中使用while hasNextInt() 时,它不接受我的输入。

当我在chooseCave() 方法中使用if hasNextInt() 时,它不接受我对playAgain 字符串的输入,并直接进入另一个游戏,但随后hasNextInt() 布尔值返回false 并且它无限发送“哪个洞穴...”的垃圾邮件。

我已经查看了错误报告以及 Java 文档和 Stack Overflow 的类似问题。请帮忙。

import java.util.Scanner;
public class Dragon {

public static void displayIntro() {
    System.out.println("You are in a land full of dragons. In front of you, ");
    System.out.println("You see two caves. In one cave, the dragon is friendly");
    System.out.println("and will share his treasure with you. The other dragon");
    System.out.println("is greedy and hungry, and will eat you on sight");
    System.out.println(' ');
}

public static int chooseCave() {
    Scanner in = new Scanner(System.in);
    int cave = 0;
    while (cave != 1 && cave != 2) {
        System.out.println("Which cave will you go into? (1 or 2)");

        cave = in.nextInt();

    }
    in.close();
    return cave;
} 

public static void checkCave(int chosenCave) {
    System.out.println("You approach the cave...");
    try
       {
       // Sleep at least n milliseconds.
       // 1 millisecond = 1/1000 of a second.
       Thread.sleep( 2000 );
       }
    catch ( InterruptedException e )
       {
       System.out.println( "awakened prematurely" );
       }
    System.out.println("It is dark and spooky...");
    try
       {
       // Sleep at least n milliseconds.
       // 1 millisecond = 1/1000 of a second.
       Thread.sleep( 2000 );
       }
    catch ( InterruptedException e )
       {
       System.out.println( "awakened prematurely" );
       }
    System.out.println("A large dragon jumps out in front of you! He opens his jaws and...");
    try
       {
       // Sleep at least n milliseconds.
       // 1 millisecond = 1/1000 of a second.
       Thread.sleep( 2000 );
       }
    catch ( InterruptedException e )
       {
       System.out.println( "awakened prematurely" );
       }

    double friendlyCave = Math.ceil(Math.random() * 2);

    if (chosenCave == friendlyCave) {
        System.out.println("Gives you his treasure!");
    }
    else {
        System.out.println("Gobbles you down in one bite!");
    }



}
public static void main(String[] args) {
    Scanner inner = new Scanner(System.in);
    String playAgain = "yes";
    boolean play = true;
    while (play) {
        displayIntro();
        int caveNumber = chooseCave();
        checkCave(caveNumber);
        System.out.println("Do you want to play again? (yes or no)");
        playAgain = inner.nextLine();
        if (playAgain == "yes") {
            play = true;
        }
        else {
            play = false;
        }
    }
    inner.close();

}

}

【问题讨论】:

    标签: java exception java.util.scanner


    【解决方案1】:

    根据其他人之前的评论:

    你关闭了第二个 Scanner,它关闭了底层的 InputStream, 因此第一个 Scanner 不能再从同一个 Scanner 读取 InputStream 和 NoSuchElementException 结果。

    解决方案:对于控制台应用程序,使用单个 Scanner 来读取 System.in.

    旁白:如前所述,请注意 Scanner#nextInt 不会 消耗换行符。确保这些在之前被消耗掉 尝试使用 Scanner#newLine() 再次调用 nextLine。

    请参阅:不要在单个 InputStream 上创建多个缓冲包装器

    我想出了这个解决方案。也许这会对某人有所帮助:

    以下代码有效:

    import java.util.Scanner;
    
    public class Main {
    
        private static String func(Scanner in) {
            String input = "";
            in = new Scanner(System.in).useDelimiter("\n");
            input = in.next();
            System.out.println("UserInput: " + input);
    
            return input;
        }
    
        public static void main(String[] args) {
    
            Scanner in = new Scanner(System.in);
    
            String s;
            s = func(in);
            System.out.println("Main: " + s);
    
            s = func(in);
            System.out.println("Main: " + s);
        }
    }
    

    并且以下代码将不起作用。这输出与线程相同的问题:

    import java.util.Scanner;
    
    public class Main {
    
        private static String func() {
            String input = "";
            Scanner s = new Scanner(System.in);
            input = s.nextLine();
            System.out.println("UserInput: " + input);
    
            input = s.nextLine();
            System.out.println("UserInput: " + input);
    
            s.close();
    
            return input;
        }
    
        public static void main(String[] args) {
    
            String s;
            s = func();
            System.out.println("Main: " + s);
    
            s = func();
            System.out.println("Main: " + s);
        }
    }
    

    【讨论】:

      【解决方案2】:

      每个人都解释得很好。让我回答什么时候应该使用这个类。

      什么时候应该使用 NoSuchElementException?

      Java 包含几种不同的方法来遍历集合中的元素。这些类中的第一个 Enumeration 是在 JDK1.0 中引入的,并且通常被认为已弃用,以支持更新的迭代类,如 Iterator 和 ListIterator。

      与大多数编程语言一样,Iterator 类包含一个hasNext() 方法,该方法返回一个布尔值,指示迭代是否还有元素。如果hasNext() 返回true,那么next() 方法将返回迭代中的下一个元素。与 Enumeration 不同,Iterator 还有一个remove() 方法,该方法删除通过next() 获得的最后一个元素。

      虽然迭代器被泛化用于Java Collections Framework 中的所有集合,但ListIterator 更专业化,并且仅适用于基于列表的集合,例如ArrayListLinkedList 等。但是,ListIterator 增加了更多功能,允许通过hasPrevious()previous() 方法在两个方向上进行迭代。

      【讨论】:

        【解决方案3】:

        别关门了

        从您的代码中删除 in.close()

        【讨论】:

        • 这重复了接受的答案,但质量要低得多。
        • 我也遇到了同样的问题。在互联网上搜索了很多,最后从我的代码中删除了 in.close() 对我有用。这就是我回答这个问题的原因。
        • 这个答案确实已经给出,并且有更好的解释。
        • @AndrewBarber 你能告诉我哪些答案告诉我删除 in.close()。我知道我没有提供任何解释,但答案是正确的。接受的答案告诉只使用 1 个扫描仪(有时这是不可能的),我说过根本不要关闭扫描仪。两个答案都有区别(如果你仔细阅读的话)。
        【解决方案4】:

        您关闭了第二个Scanner,它关闭了底层InputStream,因此第一个Scanner 不能再从相同的InputStreamNoSuchElementException 结果中读取。

        解决方案:对于控制台应用程序,使用单个Scanner 来读取System.in

        旁白: 如前所述,请注意Scanner#nextInt 不使用换行符。在尝试使用Scanner#newLine() 再次调用nextLine 之前,请确保已使用这些内容。

        见:Do not create multiple buffered wrappers on a single InputStream

        【讨论】:

        • +1,我忘了提到多个扫描仪有一个输入问题。
        • 感谢您和 syb0rg。我只需要删除带有扫描仪的方法,并将等效的方法放在主要方法中。有用!一种新的编程语言的第一次成功……感觉真的很好。 :)
        【解决方案5】:

        nextInt() 方法离开\n(结束行)符号并立即被nextLine() 拾取,跳过下一个输入。您要做的是对所有内容都使用nextLine(),然后再对其进行解析:

        String nextIntString = keyboard.nextLine(); //get the number as a single line
        int nextInt = Integer.parseInt(nextIntString); //convert the string to an int
        

        这是迄今为止最简单的避免问题的方法——不要混用你的“下一个”方法。仅使用nextLine(),然后解析ints 或单独的单词。


        另外,如果您只使用一个终端进行输入,请确保您只使用一个Scanner。这可能是异常的另一个原因。


        最后一点:将String.equals() 函数进行比较,而不是== 运算符。

        if (playAgain == "yes"); // Causes problems
        if (playAgain.equals("yes")); // Works every time
        

        【讨论】:

        • 谢谢!我希望我在这里有足够的积分来支持你。我修复了你所说的,它仍然没有工作......但好消息是,一旦我将扫描仪从方法中取出,我就可以将它全部放入 main 方法中并且它工作正常。也帮助进行号码初始化。再次感谢! :)
        【解决方案6】:

        Reimeus 是对的,您看到这一点是因为您的 chooseCave() 中的 in.close。 另外,这是错误的。

        if (playAgain == "yes") {
              play = true;
        }
        

        您应该使用等于而不是“==”。

        if (playAgain.equals("yes")) {
              play = true;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-05-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-08
          • 1970-01-01
          相关资源
          最近更新 更多