2

3つの結果を返す集計があります

{ "serverUsed" : "/127.0.0.1:27017" , "result" : [ { "_id" : "luke" , "times" : 56} , { "_id" : "albert" , "times" : 28} , { "_id" : "matt" , "times" : 28}] , "ok" : 1.0}

ただし、結果を反復処理しようとすると、コードは無限ループに入ります(理由がわかりません!!)

AggregationOutput output = coll.aggregate( match1, unwind, match2, group, sort, limit);

Iterable<DBObject> list= output.results();
        while(list.iterator().hasNext()){

            String id = (String) list.iterator().next().get("_id");
            int times = Integer.parseInt(list.iterator().next().get("times").toString());

            System.out.println("ID IS "+id+" time: "+times);
        }

また、出力は最初の結果を繰り返します。

ID IS luke time: 56
ID IS luke time: 56
ID IS luke time: 56
ID IS luke time: 56
ID IS luke time: 56
...

私は本当にわかりません;なぜこの反復が機能しないのか理解できません。助けてください!

4

3 に答える 3

6

のフィールドにアクセスするたびに新しいイテレータを使用しているようDBObjectです。つまりlist.iterator()、ループ内で数回使用しています。list.iterator().next()コレクションの最初の要素を返します。したがって、最初のにアクセスすることになりますDBObject

これを試して:

Iterable<DBObject> list= output.results();
while(list.iterator().hasNext()){
    DBObject obj = list.iterator().next();
    String id = obj.get("_id");
    int times = Integer.parseInt(obj.get("times").toString());

    System.out.println("ID IS "+id+" time: "+times);
}

または、foreachループを使用することもできます。

for (DBObject obj : output.results()) {
    String id = obj.get("_id");
    int times = Integer.parseInt(obj.get("times").toString());
    System.out.println("ID IS "+id+" time: "+times);
}
于 2013-03-23T20:22:06.083 に答える
3

これは古いスレッドであり、すでに回答済みですが、回答は最適化です。繰り返し回答が得られる実際の理由は、.iterator()を要求するたびに、リストの先頭から始まるイテレーターオブジェクトが返されるためです。

したがって、次のwhileループ条件:

list.iterator().hasNext()

常にtrueを返します。それに対応して、その後

list.iterator().next()

常に最初の要素を返します。

すべきことはこれです:

AggregationOutput output = coll.aggregate( match1, unwind, match2, group, sort, limit);
Iterable<DBObject> list= output.results();
Iterator<DBObject> iterator= list.iterator();

while(iterator.hasNext()){
    DBObject obj = iterator.next();

    String id = (String) obj.get("_id");
    int times = Integer.parseInt(obj.get("times").toString());

    System.out.println("ID IS "+id+" time: "+times);
}

しかし、技術的には、@Aquaによって言及されたforループは使用するのがはるかにクリーンです。この答えは、方法ではなく、理由を明確にするためだけのものでした。

于 2013-10-22T22:09:18.737 に答える
1

コードで考えられる欠陥の1つは、Iterator.next()メソッドを複数回呼び出していることです。その値を変数に格納し、複数回呼び出す代わりに変数を使用します。

例えば:

DBObject obj = list.iterator().next();
String id = (String) obj.get("_id"); 

int times = Integer.parseInt(obj.get("times").toString());`
于 2013-03-23T20:26:01.937 に答える