0

私がやろうとしているのは、Move オブジェクトを topMoves という名前のベクターに保存することです。多くの Move オブジェクトが存在するため、ループ内にオブジェクトを作成します。

pastPriceMap は、過去のある時点 (この場合は 1 分前) の株式の価格を格納します。currPriceMap は、最後の 1 秒以内のある時点での株式の価格を格納します。

次の例外が発生します。

スレッド「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;
}
4

3 に答える 3

3

簡潔な答え:

hasNext()への呼び出しごとに、 next()への呼び出しは 1 回だけにする必要があります。

コードには、5 つの next()とhasNext()が 1 つだけあります。

ここで、これを読んでください:http://java.sun.com/javase/6/docs/api/java/util/Iterator.html

編集

より長い答え:

基本的に、イテレータは、「何か」の要素を典型的にはコレクションに反復するために使用されますが、それは何でもかまいません (何でもが Iterator を返すことを認めてください)。

その「何か」にはいくつの要素があるかわからないかもしれないので、反復を停止する方法があるはずですよね? (配列の場合は、長さプロパティでわかりますが、イテレータは実装で使用されるデータ構造を「カプセル化」するために使用されます)とにかく。

イテレータ API は、これら 2 つのメソッドを定義します

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

イテレータに項目が 2 つしかない場合はどうなりますか?

 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 をキャッチしようと考えてはいけません。これはランタイム例外であり、コード ロジックの何かを修正する必要があることを示しています。

例外の詳細については、この回答を参照してください。

于 2009-02-24T05:11:12.053 に答える
1

新しい 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);
 }
于 2009-02-24T05:25:23.970 に答える
0
// さらに行がある間
while(scanner.hasNextLine())
{
    最後の文字列行;
    最終文字列[]単語;

    // 次の行を取得
    行 = スキャナー.nextLine();

    // 行を単語に分割します (\\s+ は空白で分割する必要があります)
    words = line.split("\\s");

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

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

    Move amove = new Move();
    amove.setSecCode(単語[2]);
    amove.setPrice(currPriceMap.get(words[3]));
    amove.setInitPrice(pastPriceMap.get(words[4]));
    topMoves.add(移動);
}
于 2009-02-24T05:07:51.220 に答える