NoElementException但我打印元素并获得预期的结果

时间:2009-02-24 05:00:48

标签: java exception vector logic

我要做的是将Move对象保存到名为topMoves的Vector中。会有很多Move对象,这就是我在循环中创建对象的原因。

pastPriceMap存储过去一段时间的股票价格(在这种情况下是一分钟前)。 currPriceMap在最后一秒内存储股票的价格。

我得到以下异常:

线程“Timer-0”中的异常java.util.NoSuchElementException

这是导致问题的一行:   amove.setInitPrice(pastPriceMap.get(iter.next()));

下面是代码段。当我执行System.out.println语句时,我得到了预期的输出:

Iterator<String> iter = sortedTopCodes.iterator();

while(iter.hasNext()){

    System.out.println(currPriceMap.get(iter.next()));
    System.out.println(pastPriceMap.get(iter.next()));

        Move amove = new Move();
    amove.setSecCode(iter.next());
    amove.setPrice(currPriceMap.get(iter.next()));
    amove.setInitPrice(pastPriceMap.get(iter.next()));
    topMoves.add(amove);
}

    return topMoves;

Move类看起来像这样:

private String secCode;
private double price;
private double initPrice;

public String getSecCode() {
    return secCode;
}
public void setSecCode(String secCode) {
    this.secCode = secCode;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}

public double getInitPrice() {
    return initPrice;
}
public void setInitPrice(double lastPrice) {
    this.initPrice = lastPrice;
}

3 个答案:

答案 0 :(得分:3)

简短回答:

每次拨打 hasNext()时,只应拨打一次 next()

在您的代码中,您有5 next(),只有一个 hasNext()

在这里,请阅读:http://java.sun.com/javase/6/docs/api/java/util/Iterator.html

编辑

更长的答案:

基本上,迭代器用于...很好地迭代“某事物”的元素,但它可以是任何东西(授予任何东西返回迭代器)。

既然你可能不知道那个“任何东西”有多少元素,那么必须有办法停止迭代吗? (如果它是一个数组,你可以通过length属性来判断,但迭代器用于“封装”实现中使用的数据结构)无论如何。

迭代器API定义了这两个方法

-hasNext(): boolean 
-next(): Object ( or <E> since Java 1.5 ) 

所以典型的习语是:

 while( iterator.hasNext() ) { // reads: while the iterator has next element
      Object o = iterator.next(); //  give me that element
 }

如果迭代器只有两个项目会怎么样?

 while( iterator.hasNext() ) { // the first time will return true, so the next line will be executed.

      Object o = iterator.next(); // give me that item. ( 1st element ) 

      Object b = iterator.next(); // oops dangerous by may work ... ( 2nd element ) 

      Object c = iterator.next(); // eeeerhhh... disaster: NoSuchElementException is thrown.

}

这就是发生在你身上的事。你没有验证迭代器是否有另一个元素,你只是检索它。如果迭代器碰巧有一些元素,它可能会工作一段时间,但是当它失败时会有一段时间(如你所见)。

顺便说一句,不要甚至想到捕获NoSuchElementException。这是一个运行时异常,它表明代码逻辑中的某些内容应该被修复。

请参阅this answer以了解有关例外情况的更多信息。

答案 1 :(得分:1)

这是一个使用new for循环的版本:

for ( String secCode : secCodeList ) {

        System.out.println(currPriceMap.get(secCode));
        System.out.println(pastPriceMap.get(secCode));

        Move amove = new Move();
        amove.setSecCode(secCode);
        amove.setPrice(currPriceMap.get(secCode));
        amove.setInitPrice(pastPriceMap.get(secCode));
        topMoves.add(amove);
}

旧时尚:

String secCode = null;    
for ( Iterator<String> it = secCodeList.iterator(); it.hasNext() ) {
    secCode = it.next();
    System.out.println(currPriceMap.get(secCode));
    System.out.println(pastPriceMap.get(secCode));

    Move amove = new Move();
    amove.setSecCode(secCode);
    amove.setPrice(currPriceMap.get(secCode));
    amove.setInitPrice(pastPriceMap.get(secCode));
    topMoves.add(amove);
 }

答案 2 :(得分:0)

// while there are more lines
while(scanner.hasNextLine())
{
    final String   line;
    final String[] words;

    // get the next line
    line = scanner.nextLine();

    // break the line up into the words (\\s+ should break it up via whitespace)
    words = line.split("\\s");

    if(words.length != 5)
    {
        throw new WhateverExceptionMakesSense(line + " must contain 5 words");
    }

    System.out.println(currPriceMap.get(words[0]));
    System.out.println(pastPriceMap.get(words[1]));

    Move amove = new Move();
    amove.setSecCode(words[2]);
    amove.setPrice(currPriceMap.get(words[3]));
    amove.setInitPrice(pastPriceMap.get(words[4]));
    topMoves.add(amove);
}