なぜjavaが現れたのか.util.C o n c u r r e n t ModificationException異常?
仕事中にc o n c u r r e ntmodificationexceptionに出会った.コードは次のとおりです.
removeメソッドを実行した後、ループを実行し、iter.next()の場合java.util.c o n c u r r e n t modificationexception(もちろん、removeが最後であればnext()操作は実行されません)
次はソースコードを見てみましょう
次にabstractlistを見てみましょう
したがって,c o n c u r r e n t modificationexceptionを生成する理由は,
remove(object o)メソッドを実行した後,modcountとexpectedmodcountが等しくなくなったためである.次にnext()メソッドにコードが実行されるとcheckforcomodification()が判断され,2つの数値が等しくないことが判明し,このexceptionが投げ出された.br>このexceptionを避けるにはremove()メソッドを使用する必要があります.
ここでadd(object o)メソッドを見ないのも同様の理由ですが、対応するadd()メソッドはありません.一般的には、listを別途作成しました
以下はネット上の他の解釈で、
iteratorは独立したスレッドで動作し、mutexロックを持っています.iteratorが作成すると元のオブジェクトを指す単一チェーンインデックステーブルが作成され、元のオブジェクトの数が変化するとこのインデックステーブルの内容は同期的に変化しないため、インデックスポインタが後ろに移動すると反復するオブジェクトが見つからないためfail-fast原則に従ってiteratorはすぐにjavaを投げ出す.util.c o n c u r r e n t modification exception異常.
したがってiteratorは、作業中に反復されたオブジェクトを変更することは許されません.しかし、iterator自体の方法remove()を使用してオブジェクトを削除することができます.iterator.remove()メソッドは、現在の反復オブジェクトを削除しながらインデックスの一貫性を維持します.
list list = ...;for(iterator iter = list.iterator(); iter.hasnext();) { object obj = iter.next(); ... if(***) { list.remove(obj); }}
removeメソッドを実行した後、ループを実行し、iter.next()の場合java.util.c o n c u r r e n t modificationexception(もちろん、removeが最後であればnext()操作は実行されません)
次はソースコードを見てみましょう
public interface iterator<e> { boolean hasnext(); e next(); void remove();}public interface collection<e> extends iterable<e> { ... iterator<e> iterator(); boolean add(e o); boolean remove(object o); ...}
ここには2つのremoveメソッドがあります次にabstractlistを見てみましょう
public abstract class abstractlist<e> extends abstractcollection<e> implements list<e> { //abstractcollection list collection protected transient int modcount = 0; private class itr implements iterator<e> { // itr int cursor = 0; int lastret = -1; int expectedmodcount = modcount; public boolean hasnext() { return cursor != size(); } public e next() { checkforcomodification(); // try { e next = get(cursor); lastret = cursor++; return next; } catch(indexoutofboundsexception e) { checkforcomodification(); throw new nosuchelementexception(); } } public void remove() { if (lastret == -1) throw new illegalstateexception(); checkforcomodification(); try { abstractlist.this.remove(lastret); // remove if (lastret < cursor) cursor--; lastret = -1; expectedmodcount = modcount; // expectedmodcount , concurrentmodificationexception } catch(indexoutofboundsexception e) { throw new concurrentmodificationexception(); } } final void checkforcomodification() { if (modcount != expectedmodcount) // expectedmodcount modcount , concurrentmodificationexception throw new concurrentmodificationexception(); } } }remove(object o) arraylist :public boolean remove(object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementdata[index] == null) { fastremove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementdata[index])) { fastremove(index); return true; } } return false;}private void fastremove(int index) { modcount++; // modcount ....}
したがって,c o n c u r r e n t modificationexceptionを生成する理由は,
remove(object o)メソッドを実行した後,modcountとexpectedmodcountが等しくなくなったためである.次にnext()メソッドにコードが実行されるとcheckforcomodification()が判断され,2つの数値が等しくないことが判明し,このexceptionが投げ出された.br>このexceptionを避けるにはremove()メソッドを使用する必要があります.
ここでadd(object o)メソッドを見ないのも同様の理由ですが、対応するadd()メソッドはありません.一般的には、listを別途作成しました
以下はネット上の他の解釈で、
iteratorは独立したスレッドで動作し、mutexロックを持っています.iteratorが作成すると元のオブジェクトを指す単一チェーンインデックステーブルが作成され、元のオブジェクトの数が変化するとこのインデックステーブルの内容は同期的に変化しないため、インデックスポインタが後ろに移動すると反復するオブジェクトが見つからないためfail-fast原則に従ってiteratorはすぐにjavaを投げ出す.util.c o n c u r r e n t modification exception異常.
したがってiteratorは、作業中に反復されたオブジェクトを変更することは許されません.しかし、iterator自体の方法remove()を使用してオブジェクトを削除することができます.iterator.remove()メソッドは、現在の反復オブジェクトを削除しながらインデックスの一貫性を維持します.