ArrayListは要素の削除中にトラバースするため、バグが発生する可能性があります。

次のように、ArrayListをトラバースして、条件に従って要素を削除する必要がある場合があります。

    public static void main(String[] args) {
        String fff = new String("fff");
        String a=new String();
        ArrayList<String> list= new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        for(String s:list) {
            if("aa".equals(s)) {
                list.remove("aa");
            }
        }
    }

しかし、これは次のエラーを報告し

ます:生成されたクラスファイルの逆コンパイル結果を見てみましょう:

    public static void main(String[] var0) {
        new String("fff");
        new String();
        ArrayList var3 = new ArrayList();
        var3.add("aa");
        var3.add("bb");
        var3.add("cc");
        Iterator var4 = var3.iterator();

        while(var4.hasNext()) {
            String var5 = (String)var4.next();
            if ("aa".equals(var5)) {
                var3.remove("aa");
            }
        }
    }

ここでのトラバースでは、ArrayListによって実装されたイテレーターのhasNext()およびnext()メソッドを使用していますが、削除にはArrayListのremove(Object o)メソッドを使用しています。このように、イテレータはArrayList内の要素の変更を認識できません。たとえば、ArrayList内の要素が削除され、その後ろの要素が1つ前に移動します。元のイテレータの位置にある要素は削除され、後ろの要素に置き換えられますが、イテレータはそうではありません次の反復では、この要素がトラバースされたと見なされ、直接スキップされます。
この動作は、ArrayListで監視されます
。ModCountとExpectedModCountが等しく、ModCountが実行されるたびにArrayList.remove()がインクリメントされることがわかります。

イテレーターは、ModCountとExpectedModCountが等しいことを確認します。

次に、ConcurrentModificationExceptionをスローします

正しいアプローチ:

iterator.remove()がここで行うことを見てみましょう

。実際、list.remove(Object o)を呼び出すときに、「expectedModCount = modCount;」という文を追加すると、それらの値は次の反復で等しくなります。

補足:
javacを使用してjavaを.classファイル(javac [-encoding utf-8] javaName.java)にコンパイルし、それを開発ツールで開いたり、.classファイルの逆コンパイルされたコンテンツを表示したり、開発ツールで直接表示したりできます。クラスファイル(逆コンパイルされたファイル)を表示します。一部の「非表示」メソッドの特定の実装を確認するには、
次のようにします。for(String s:list){
if( "aa" .equals(s)){
list.remove( "aa");
}
}

String var5;
while(var4.hasNext()){
var5 =(String)var4.next();
if( "aa" .equals(var5)){
var3.remove( "aa");
注:jdkを使用する場合javap命令、つまりjavap classNameを使用すると、メソッド名のみがソースコードの元の外観に表示される場合があります。

おすすめ

転載: www.cnblogs.com/superyoungy/p/12682340.html