NoElementException, но я печатаю элемент и получаю ожидаемый результат - PullRequest
0 голосов
/ 24 февраля 2009

Я пытаюсь сохранить объекты Move в векторе с именем topMoves. Будет много объектов Move, поэтому я создаю объект внутри цикла.

В программе pastPriceMap хранятся цены на акции за прошедшее время (в данном случае минуту назад). CurrPriceMap хранит цену акций некоторое время в течение последней секунды.

Я получаю следующее исключение:

Исключение в потоке "Таймер-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 ]

3 голосов
/ 24 февраля 2009

Краткий ответ:

Для каждого вызова 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. Это исключение времени выполнения, и оно указывает, что что-то в логике вашего кода должно быть исправлено.

См. этот ответ , чтобы узнать больше об исключениях.

1 голос
/ 24 февраля 2009

Вот версия, использующая новые циклы 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);
 }
0 голосов
/ 24 февраля 2009
// 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...