什么是java.util.NoSuchElementException以及如何修复它?

4

我尝试编程一个海战游戏,在用户输入他们的猜测坐标时遇到了错误:

Exception in thread "main" java.util.NoSuchElementException


    at java.util.Scanner.throwFor(Unknown Source)
        at java.util.Scanner.next(Unknown Source)
        at java.util.Scanner.nextInt(Unknown Source)
        at java.util.Scanner.nextInt(Unknown Source)
        at game.User.takeTurn(User.java:121)
        at game.Game.main(Game.java:61)

这里是 User.takeTurn() 方法,错误发生的地方:

    static void takeTurn() {
           System.out.println("Yout turn!");
           System.out.println("Enter your x guess:");
           Scanner scanInput = new Scanner(System.in);
           int x;
           x = scanInput.nextInt();
           System.out.println("You entered "+ x + ", Now enter your y     coord:");
           int y;
           y = scanInput.nextInt();
           System.out.println("You entered + " + y);
           if(Board.aiBoard[x][y] == 2) {
               System.out.println("Hit! You got a hit at: " + x + "," + y);
               Board.enemyBoardDisplay[x][y] = 'h';
               Board.aiBoard[x][y] = 3;
           }
           else {
            System.out.println("Miss!");
            Board.enemyBoardDisplay[x][y] = 'x';
            Board.aiBoard[x][y] = 1;
          }

           scanInput.close();
      }

我不确定是否重要,但在课堂上我还使用了另一个扫描器。如果您需要更多的代码帮助,请告诉我。谢谢!

编辑1: 好的,即使我执行了scanInput.hasNextInt(),它也没有起作用。我还加入了一个else语句,给x赋了一个值,但现在x总是拥有else语句给出的值。它甚至不要求输入,而是默认为该值。但我不希望它进入默认状态,我希望用户选择。

编辑2:这是我在主存根中调用代码的地方

while (gameOn == true) {
            if (turn == 0) {
                User.takeTurn();
                Board.sunkCheck();
                if (gameOn == false)
                    break;
            }

            else if (turn == 1) {
                Computer.takeTurn();
                Board.sunkCheck();
                if (gameOn == false)
                    break;
            }

这是我之前在同一个类中使用扫描器的位置,现在我正试图使用扫描器:

System.out
                .println("\n Please enter the first x value for your ship  (Note, this will be the first point, from this point the \n"
                        + " ship can either go vertically downward or horizontally to the right so please choose the topmost point or leftmost \n"
                        + "point to do this. Also, the board is 10x10 but due to java array indexing the coordinates go x 0-9 y 0-9: ");
        try {
        Scanner coord = new Scanner(System.in);
        userX = coord.nextInt();
        System.out.println("You entered: " + userX);
        System.out.println("Now enter the y coordinate for this point: ");
        userY = coord.nextInt();
        System.out.println("You entered: " + userY);
        System.out
                .println("Please choose the direction of your ship. Enter v for verticle or h for horizontal(case sensitive): ");
        dir = (char) System.in.read();
        coord.close();
        }
        catch(InputMismatchException e) {
            System.out.println("Good job doof, since you tried to troll we did all the values for you!");
            userX = 3;
            userY = 3;
            dir = 'v';
        }

1
你是否看过 API 文档?引用:“由各种存取器方法抛出,表示请求的元素不存在。” - Jesper
1
还有Scanner.nextInt()的文档:“如果输入耗尽,则抛出NoSuchElementException”。 - Jesper
2个回答

3
在使用Scanner中的scanInput.hasNextInt()之前,您可能需要检查next元素是否存在。
更新: 如果您使用上述Scanner coord = new Scanner(System.in);,然后调用带有Scanner scanInput = new Scanner(System.in);的函数而不关闭coord Scanner,则会出现问题。
扫描仪将继续消耗流 - 这可能会导致意外的副作用。
在使用另一个扫描仪之前,您可能需要关闭第一个(此处了解更多信息)。
更新: 当您关闭coord.close()时,您正在关闭System.in,当您尝试从中重新读取时,它将抛出异常。
您可以创建自己的Scanner一次并重复使用它,而不是每次需要输入时都重新打开流。

啊,好主意,但我已经关闭了第一个,我执行了coord.close();。 - Ashwin Gupta
等一下,抱歉我没点开你的链接,我想我知道该怎么做了。我可以在这个类里使用之前的那个扫描器来完成吗? - Ashwin Gupta
@AshwinGupta,你可以将它传递给函数。 - nitishagar
@AshwinGupta 尝试只使用一个 Scanner 对象进行传参,看看是否能解决你的问题。 - nitishagar
好的,我尝试了一下,现在遇到的问题是,在类文件末尾关闭扫描器后,它显示“语法错误:缺少标识符”。 - Ashwin Gupta
太好了!你说的完美地解决了我的问题,非常感谢!我希望能点赞,但是我的声望还不够。唯一的问题是扫描仪从未关闭,但我想这应该不是问题吧? - Ashwin Gupta

1

当您尝试从扫描器中读取输入并且不存在输入时,会出现NoSuchElementException。因此,在获取输入之前,应该检查扫描器是否有可供您使用的输入,例如:

if (scanInput.hasNextInt()) {
    x = scanInput.nextInt();
}

嗯,当我这样做时,IDE会将此后的所有代码都标记为错误,因为 x 可能没有值。所以我添加了一个 else 语句来给 x 赋值,但现在 x 总是具有 else 语句赋予的值。是什么导致扫描器没有输入可供消耗? - Ashwin Gupta
@Ashwin Gupta。你试过那个 while 吗?也试试这个 int x = scanInput.nextInt(); [声明和赋值在同一行] - frunkad
好的,我在发布问题之前就已经完成了你说的第二件事情,我会尝试使用while循环,谢谢! - Ashwin Gupta
好的,我刚试了一下你的整个东西!那确实有点起作用。它最终提示我输入一个输入,而之前它并没有让我这样做(只是默认为我的 else),但现在输入流不会关闭,就像它从未终止程序一样,它只是一直让我输入。 - Ashwin Gupta
然后使用 BufferedReader - frunkad
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接