3

現在、ArrayList の反復処理に問題があります。ここでいくつかの投稿を読みましたが、何も問題を解決していないようです。これが私のコードです:

//restaurants contains a list of all restaurants and i want to filter them
List<Restaurant> newList = new ArrayList<Restaurant>();
List<Restaurant> allRestaurants = new ArrayList<Restaurant>(restaurants);
if (query != null && query.length() > 0 && !query.equals("*")) {
            synchronized (allRestaurants) {
                for (Iterator<Restaurant> it = allRestaurants.iterator(); it
                        .hasNext();) {
                    Restaurant restaurant = it.next();
                    if (restaurant.getCity().contains(query)) {
                        synchronized (newList) {
                            newList.add(restaurant);
                        }
                    } else {
                        newList = allRestaurants;
                    }
                }
            }

これは、私がここで読んだいくつかのアイデアを使用してコードを変更したものです (for-each-loop の代わりに反復子を使用して同期)。メソッド全体を同期しても例外が発生します。

例外は次の行で発生しています。

Restaurant restaurant = it.next();

わかりません。この行ではリストを操作していません。なぜこれが起こっているのですか、どうすれば修正できますか?

4

5 に答える 5

0

ループ内の反復に使用される ArrayList を変更することはできません。これは ConcurrentModificationException が言うこと ( http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ConcurrentModificationException.html ) であり、newList = allRestaurants;さらにnewList.add(restaurant);リストを変更する可能性がありますallRestaurants

だからあなたができることは

  1. 別のリストを作成する
  2. 変更する項目をそのリストに入れる
  3. ループaddAllに新しいリスト(またはremoveAll)を古いリストに追加/削除します

詳細については、 http://www.javacodegeeks.com/2011/05/void-concurrentmodificationexception.htmlをご覧ください。

于 2013-03-13T20:33:03.067 に答える
0

else ブランチで

else {
   newList = allRestaurants;
}

に設定newListしましたallRestaurants。次のnewList.add(restaurant);変更は allRestaurants-list を変更します。

が呼び出されると例外がスローit.next()されます。これは、反復子がそのソースが変更されたかどうかをチェックするためです。

于 2013-03-13T20:28:39.460 に答える
0

失敗は次のように始まります。

newList = allRestaurants;

これは、両方の参照が同じリスト (つまり、繰り返し処理しているリスト) を指しています。次に、次の操作を行います。

newList.add(restaurant);

リストの修正。の javadoc からConcurrentModificationException:

この例外は、オブジェクトが別のスレッドによって同時に変更されたことを常に示すわけではないことに注意してください。1 つのスレッドが、オブジェクトのコントラクトに違反する一連のメソッド呼び出しを発行すると、オブジェクトはこの例外をスローする可能性があります。たとえば、フェイルファスト反復子を使用してコレクションを反復処理しているときに、スレッドがコレクションを直接変更すると、反復子はこの例外をスローします。

于 2013-03-13T20:29:23.467 に答える
0

あなたの問題はelse句にあります。

         newList = allRestaurants;

そのため、例外が発生します

于 2013-03-13T20:29:27.043 に答える