7

ConcurrentModificationExcrptionマスター リストの後にサブ リストをクリアすると、次のコードが をスローするのに、サブ リストをクリアしてからマスター リストをクリアするとスローしないのはなぜですか?

ArrayList<Integer> masterList = new ArrayList<Integer>();
List<Integer> subList;

// Add some values to the masterList
for (int i = 0; i < 10; i++) {
    masterList.add(i * i);
}

// Extract a subList from the masterList
subList = masterList.subList(5, masterList.size() - 1);

// The below throws ConcurrentModificationException
masterList.clear();
subList.clear(); // Exception thrown in this line

// The below doesn't throw any exception
subList.clear();
masterList.clear(); // No exception thrown. Confused??
4

4 に答える 4

4

SubList独立したエンティティではありませんが、元のリストのビューを提供しているだけで、内部的に同じリストを参照しています。したがって、その設計は、基になるリストが構造的に変更された場合 (要素の追加/削除)、その契約を履行できないように思われます。

ここで SubList のソース コードに見られるように、このメソッドcheckForComodificationは基になるリストが変更されているかどうかをチェックします。したがって、modCount(リストが構造的に変更された回数) の値がSubListparent と同じでないArrayList場合、それはスローされます。ConcurrentModificationException

そのため、作成元の親ArrayListをクリアするSubListと、特定の操作SubListで ConcurrentModificationExceptionが発生する可能性があります。

于 2013-07-27T16:20:49.543 に答える
2

subList上のビューmasterListです。基礎となるコレクションは 1 つだけです。masterList は一種のsupersetサブリストです。そう、

  • sublistmasterlist's要素が削除された場合は存在できません//例外ケース
  • masterlistsublist's要素が削除された場合に存在できます//OK
于 2013-07-27T16:05:51.827 に答える
2

ArrayList doc subList()によると、元の ArrayList に基づくサブリストが返されるため、元の変更が subList に変更された場合、subList.clear() を実行すると、サブリスト自体はもう存在しません。

于 2013-07-27T16:07:03.080 に答える
2

API ドキュメントから:

バッキング リスト (つまり、このリスト) が返されたリスト以外の方法で構造的に変更された場合、このメソッドによって返されるリストのセマンティクスは未定義になります。(構造的な変更とは、このリストのサイズを変更するもの、または進行中の反復が誤った結果をもたらす可能性があるような方法でそれを混乱させるものです。)

もちろん、未定義のセマンティクスは、例外をスローすることが許可されていることを意味します (実際、これはおそらく最も賢明な方法です)。

したがって、サブリストのサイズを変更して、それらの変更をメイン リストに反映させることはできますが、その逆は当てはまりません。

于 2013-07-27T16:07:27.673 に答える