java.util.NoSuchElementException错误,查找可能的原因,仍然无法修复它

时间:2013-10-31 16:26:52

标签: java nosuchelementexception

我收到java.util.NoSuchElementException错误。出于以下原因,我们收到此错误。

  1. 如果我们在阅读之前没有检查文件是否有下一行, 然后它在读完最后一行后抛出异常,因为它正在尝试 阅读不存在的一行。
  2. 文件格式混乱
  3. 我认为我使用的文件格式是正确的,我也在检查它之前检查下一行,但我仍然收到错误。

    当我使用print语句调试它时,它会打印所有行并在读完最后一行后抛出java.util.NoSuchElementException错误。

    请帮帮我

    以下是代码:

     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();
        }
    }
    

    例外(从评论中复制):

      

    线程“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)   在OrderBook.MainMethod.main(MainMethod.java:50)

1 个答案:

答案 0 :(得分:0)

您正在尝试使用不存在的令牌。 你做了一些next()调用而不检查是否有下一个。 在你的情况下,我怀疑文件末尾的换行符会给你一个空行作为输入。 扫描程序将看到一个新行,但由于它不包含令牌,调用“next()”将导致错误。

如果文件中的块之间有空行,则会发生同样的情况。

您可以使用的一件事是:

public boolean hasNext(String pattern) 

而不是

next()

这样可以让您在不使用令牌的情况下进行预测。

所以代替:

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
}

你可以这样做:

if (reader.hasNext("A") {
    reader.next(); // consume A
    int ts = reader.nextInt(); // get id
    // ... etcetera
} else if (reader.hasNext("X") {

}

我还建议您使用nextInt()而不是nextString,然后调用parseInt

另一件事:你甚至可以通过这样做来更好地阅读你的代码:

if (reader.hasNext("A") {
    handleAddition(reader);
}

然后再定义一个只处理这种情况的方法。 你的主要方法如下:

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();
}

现在你的方法很好而且简短,并且所有特定的操作都采用具有自己名称的方法。

如果在主循环内部使用A,X,R等,或者实际的处理程序方法,那么我唯一不会百分之百关于它的问题。我更喜欢在方法内部消费。

希望它有所帮助。