NoElementException, но я распечатываю элемент и получаю ожидаемый результат

Я пытаюсь сохранить объекты 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;
}

person Ankur    schedule 24.02.2009    source источник


Ответы (2)


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

Для каждого вызова hasNext () должен быть только один вызов next ().

В вашем коде есть 5 next () только с одним hasNext ()

Прочтите здесь: http://java.sun.com/javase/6/docs/api/java/util/Iterator.html.

ИЗМЕНИТЬ

Более длинный ответ:

В основном итератор используется для ... ну итератора элементов "чего-то", типично коллекции, но это может быть что угодно (при условии, что что-либо возвращает Iterator).

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

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

person OscarRyz    schedule 24.02.2009
comment
Спасибо. Заменил iter.next () на secCodeIter и определил String secCodeIter = iter.next () - person Ankur; 24.02.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);
 }
person Clint    schedule 24.02.2009
comment
С точки зрения логики все по-другому. currPrice и pastPrice не совпадают даже в исходном посте. :) Никакого негатива. - person Adeel Ansari; 24.02.2009