java.util.NoSuchElementException 错误,查找可能的原因,仍然无法修复
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19711841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.util.NoSuchElementException error, looked for possible reasons, still can't fix it
提问by user2942227
I am getting java.util.NoSuchElementException error. We get this error for the following reasons.
我收到 java.util.NoSuchElementException 错误。我们收到此错误的原因如下。
- If we don't check if the file has next line before reading it, then it throws exception after reading last line since it is trying to read a line which doesn't exist.
- Format of the file is messed up
- 如果我们在读取文件之前不检查文件是否有下一行,那么它会在读取最后一行后抛出异常,因为它试图读取不存在的行。
- 文件格式乱了
I think that the format of the file I m using is correct and I am also checking for next line before reading it but I am still getting the error.
我认为我使用的文件格式是正确的,我也在阅读前检查下一行,但我仍然收到错误消息。
When I debug it using print statement, it prints all the line and throws java.util.NoSuchElementExceptionerror after reading last line.
当我使用 print 语句调试它时,它会打印所有行并java.util.NoSuchElementException在读取最后一行后抛出错误。
Please help me out
请帮帮我
Here is the code :
这是代码:
public static void InterpretMessageFromFile() throws FileNotFoundException{
File inputfile = new File("filepath");
Scanner reader = new Scanner(inputfile);
try {
while (reader.hasNextLine()) {
String MessageType = reader.next();
int IsAdd = MessageType.compareToIgnoreCase("A");
int IsCancel = MessageType.compareToIgnoreCase("X");
int IsDelete = MessageType.compareToIgnoreCase("D");
int IsExecute = MessageType.compareToIgnoreCase("E");
int IsReplace = MessageType.compareToIgnoreCase("U");
//if the type of order is add order to existing Order Book
if (IsAdd == 0) {
String retrieve_ts = reader.next();
int ts = Integer.parseInt(retrieve_ts);
String retrieve_id = reader.next();
int id = Integer.parseInt(retrieve_id);
String or_side = reader.next();
String retrieve_share = reader.next();
int share = Integer.parseInt(retrieve_share);
String retrieve_price = reader.next();
int price = Integer.parseInt(retrieve_price);
System.out.println("Add Order : Id is " + id );
AddOrderToExistingBook.AddNewOrder(id, ts, or_side, share, price);
}
//if it is cancel order
if (IsCancel == 0){
String retrieve_ts = reader.next();
int ts = Integer.parseInt(retrieve_ts);
String retrieve_id = reader.next();
int id = Integer.parseInt(retrieve_id);
System.out.println("Cancel Order : Id is " + id + " time stamp is : " + ts );
CancelOrder.CancelPartOfOrder(id, ts);
}
}
}
}
finally {
reader.close();
}
}
Exception(copied from comments):
例外(从评论中复制):
Exception in thread "main" java.util.NoSuchElementException at java.util.Scanner.throwFor(Scanner.java:907) at java.util.Scanner.next(Scanner.java:1416) at OrderBook.InterpretOrderBookUpdateMessage.InterpretMessageFromFile(InterpretOrde??rBookUpdateMessage.java:20) at OrderBook.MainMethod.main(MainMethod.java:50)
OrderBook.InterpretOrderBookUpdateMessage.InterpretMessageFromFile(InterpretOrde? ?rBookUpdateMessage.java:20) 在 OrderBook.MainMethod.main(MainMethod.java:50)
采纳答案by Joeblade
you are trying to consume a token that is not there. you do a number of next() calls without checking if there is next. in your case, I suspect a newline at the end of your file gives you an empty line as input. the scanner will see a new line, but as it doesn't contain tokens, calling "next()" will cause an error.
您正在尝试使用不存在的令牌。你做了一些 next() 调用而不检查是否有下一个。就您而言,我怀疑文件末尾的换行符为您提供了一个空行作为输入。扫描器将看到一个新行,但由于它不包含标记,因此调用“next()”将导致错误。
the same would happen if you have empty lines between blocks in your file.
如果文件中的块之间有空行,也会发生同样的情况。
one thing you can use is:
您可以使用的一件事是:
public boolean hasNext(String pattern)
instead of
代替
next()
this will let you do a lookahead without consuming a token.
这将使您在不消耗令牌的情况下进行前瞻。
so instead of:
所以而不是:
String MessageType = reader.next();
int IsAdd = MessageType.compareToIgnoreCase("A");
int IsCancel = MessageType.compareToIgnoreCase("X");
// .... left out other classes
//if the type of order is add order to existing Order Book
if (IsAdd == 0){
// .. do stuff
}
you can do something like:
您可以执行以下操作:
if (reader.hasNext("A") {
reader.next(); // consume A
int ts = reader.nextInt(); // get id
// ... etcetera
} else if (reader.hasNext("X") {
}
I would also recommend you use nextInt() instead of nextString and then calling parseInt
我还建议您使用 nextInt() 而不是 nextString 然后调用 parseInt
One other thing: you can even make your code better to read by doing:
另一件事:您甚至可以通过执行以下操作使您的代码更好地阅读:
if (reader.hasNext("A") {
handleAddition(reader);
}
and then later on define a method that only handles this case. your main method will look like:
然后稍后定义一个只处理这种情况的方法。您的主要方法将如下所示:
try
{
while (reader.hasNextLine())
{
if (reader.hasNext("A")) {
handleAdd(reader);
} else if (reader.hasNext("X")) {
handleCancel(reader);
} else if (reader.hasNext("D")) {
handleDelete(reader);
} else if (reader.hasNext("E")) {
handleExecute(reader);
} else if (reader.hasNext("R")) {
handleReplace(reader);
} else {
// unexpected token. pretty sure this is the case that triggers your exeception.
// basically log as info and ignore.
reader.nextLine();
}
}
}
finally
{
reader.close();
}
Now your method is nice and short, and all the specific actions are taken in methods with their own name.
现在您的方法既美观又简短,并且所有特定操作都在具有自己名称的方法中执行。
the only thing I'm not 100% about if it it's good practice to consume A, X, R, etc... inside the main loop, or the actual handler method. I prefer to consume inside the method personally.
我唯一不是 100% 关于在主循环或实际处理程序方法中使用 A、X、R 等是否是一种好的做法。我个人更喜欢在方法内部使用。
hope it helps.
希望能帮助到你。

