2009-02-24 9 views
0

Ce que j'essaie de faire est de sauvegarder un objet Move dans un vecteur appelé topMoves. Il y aura beaucoup d'objets Move, c'est pourquoi je crée l'objet dans la boucle. PastPriceMap stocke les prix des stocks à un moment donné (dans ce cas il y a une minute). Le currPriceMap stocke le prix des actions dans la dernière seconde.NoElementException mais j'imprime l'élément et obtiens le résultat attendu

je reçois l'exception suivante:

Exception dans le thread "Timer 0" java.util.NoSuchElementException

Ceci est la ligne qui est à l'origine du problème: amove.setInitPrice (pastPriceMap.get (iter.next()));

L'extrait de code est ci-dessous. Quand je fais les instructions System.out.println je reçois le résultat attendu:

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; 

La classe Move ressemble à ceci:

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

Répondre

3

Réponse courte:

Pour chaque appel à hasNext() il devrait y avoir un seul appel à next()

Dans votre code, vous avez 5 suivant() avec un seul hasNext()

Ici, lisez ceci: http://java.sun.com/javase/6/docs/api/java/util/Iterator.html

EDIT

plus long réponse:

Fondamentalement, un itérateur est utilisé pour ... bien itérer les éléments de "quelque chose" typiquement une collection mais cela pourrait être n'importe quoi (à condition que n'importe quoi renvoie un Iterator).

Puisque vous ne connaissez peut-être pas combien d'éléments a ce "quelque chose", il doit y avoir un moyen d'arrêter l'itération? (si c'était un tableau, vous pouvez dire par la propriété length, mais l'itérateur est utilisé pour "encapsuler" la structure de données utilisée dans l'implémentation) Quoi qu'il en soit.

L'API définit iterator ces deux méthodes

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

donc l'idiome typique est la suivante:

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

Ce qui se passe si l'itérateur a seulement deux éléments?

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. 

} 

Ceci est ce qui vous arrive. Vous n'avez pas vérifié si l'itérateur a un autre élément, vous venez de le récupérer.Si l'itérateur arrive à avoir des éléments, cela peut fonctionner pendant un moment mais il y aura un temps (comme vous venez de le voir) quand il échoue. Par ailleurs, NE PAS même penser à attraper NoSuchElementException. C'est une exception d'exécution et cela indique que quelque chose dans votre logique de code devrait être corrigé. Pour plus d'informations sur les exceptions, voir this answer.

+0

Merci. Remplacé le iter.next() par secCodeIter et défini chaîne secCodeIter = iter.next() – Ankur

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

Voici une version en utilisant la nouvelle pour les boucles:

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

de la façon plus:

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

Son différent dans la mesure où la logique va. currPrice et pastPrice ne sont pas les mêmes, même dans le message original. :) Aucun négatif prévu. –

Questions connexes