![](/img/trans.png)
[英]Exception in thread “main” java.util.NoSuchElementException?
[英]Exception in thread "main" java.util.NoSuchElementException
每当我运行它时, 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
并发送垃圾邮件“Which Cave.. 。“ 无限地。
我已经浏览了错误报告以及 Java 文档和堆栈溢出的类似问题。 请帮忙。
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();
}
}
您关闭了关闭底层InputStream
的第二个Scanner
,因此第一个Scanner
无法再从同一个InputStream
读取,并且结果为NoSuchElementException
。
解决方案:对于控制台应用程序,使用单个Scanner
从System.in
读取。
旁白:如前所述,请注意Scanner#nextInt
不消耗换行符。 确保在使用Scanner#newLine()
再次尝试调用nextLine
之前消耗了这些。
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()
,然后解析int
或单独的单词。
此外,如果您只使用一个终端进行输入,请确保您只使用一台Scanner
。 这可能是例外的另一个原因。
最后一点:将String
与.equals()
函数进行比较,而不是==
运算符。
if (playAgain == "yes"); // Causes problems
if (playAgain.equals("yes")); // Works every time
只是不要靠近
从您的代码中删除in.close()
。
Reimeus是正确的,你看到这一点,因为在你的chooseCave in.close的()。 另外,这是错误的。
if (playAgain == "yes") {
play = true;
}
您应该使用等于而不是“==”。
if (playAgain.equals("yes")) {
play = true;
}
每个人都解释得很好。 让我回答什么时候应该使用这个类。
什么时候应该使用 NoSuchElementException?
Java 包括几种不同的方法来迭代集合中的元素。 这些类中的第一个 Enumeration 是在JDK1.0
中引入的,通常被认为已弃用,以支持更新的迭代类,如 Iterator 和 ListIterator。
与大多数编程语言一样,Iterator 类包含一个hasNext()
方法,该方法返回一个布尔值,指示迭代是否有更多元素。 如果hasNext()
返回true
,则next()
方法将返回迭代中的下一个元素。 与枚举不同,迭代器还有一个remove()
方法,它删除通过next()
获得的最后一个元素。
虽然 Iterator 被泛化为用于Java Collections Framework
中的所有集合, ListIterator
更加专业化并且只适用于基于 List 的集合,如ArrayList
、 LinkedList
等。 然而, ListIterator
增加了更多的功能,允许迭代通过hasPrevious()
和previous()
方法在两个方向上遍历。
根据其他人之前的评论:
您关闭了关闭底层 InputStream 的第二个 Scanner,因此第一个 Scanner 无法再从同一个 InputStream 中读取,并且会产生 NoSuchElementException 结果。
解决方案:对于控制台应用程序,使用单个扫描器从 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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.