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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:36:34  来源:igfitidea点击:

java.util.NoSuchElementException error, looked for possible reasons, still can't fix it

javanosuchelementexception

提问by user2942227

I am getting java.util.NoSuchElementException error. We get this error for the following reasons.

我收到 java.util.NoSuchElementException 错误。我们收到此错误的原因如下。

  1. 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.
  2. Format of the file is messed up
  1. 如果我们在读取文件之前不检查文件是否有下一行,那么它会在读取最后一行后抛出异常,因为它试图读取不存在的行。
  2. 文件格式乱了

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.

希望能帮助到你。