【问题标题】:NoElementException but I print the element and get the expected resultNoElementException 但我打印了元素并得到了预期的结果
【发布时间】:2009-02-24 05:00:48
【问题描述】:

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

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

我得到以下异常:

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

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

代码 sn-p 如下。当我执行 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;
}

【问题讨论】:

    标签: java exception vector logic


    【解决方案1】:

    简答:

    对于 hasNext() 的每次调用应该只有一次对 next()

    的调用

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

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

    编辑

    更长的答案:

    基本上,迭代器用于......很好地迭代“某物”的元素,通常是一个集合,但它可以是任何东西(假设任何东西都返回一个 Iterator)。

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

    迭代器 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 以了解有关异常的更多信息。

    【讨论】:

    • 谢谢。将 iter.next() 替换为 secCodeIter 并定义 String secCodeIter = iter.next()
    【解决方案2】:

    这是一个使用新 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);
     }
    

    【讨论】:

    • 就逻辑而言,它是不同的。即使在原始帖子中,currPrice 和 pastPrice 也不相同。 :) 没有负面的意图。
    【解决方案3】:
    // 当有更多行时 而(扫描仪.hasNextLine()) { 最后的字符串行; 最后的 String[] 个单词; // 获取下一行 线 = 扫描仪.nextLine(); // 将行拆分为单词(\\s+ 应该通过空格将其拆分) words = line.split("\\s"); if(words.length != 5) { throw new WhatExceptionMakesSense(line + " 必须包含 5 个单词"); } System.out.println(currPriceMap.get(words[0])); System.out.println(pastPriceMap.get(words[1])); 移动 amove = new Move(); amove.setSecCode(words[2]); amove.setPrice(currPriceMap.get(words[3])); amove.setInitPrice(pastPriceMap.get(words[4])); topMoves.add(amove); }

    【讨论】:

      猜你喜欢
      • 2020-02-22
      • 2022-08-12
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      相关资源
      最近更新 更多