リストまたはマップ内の要素を横断して削除する方法はたくさんあります。不適切に使用すると問題が発生します。以下のこの記事から学びましょう。
1.リストトラバーサル中に要素を削除します
インデックスサブスクリプトトラバーサルを使用します
例:リストで2を削除します
public static void main(string [] args){list <integer> list = new ArrayList <Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); for(int i = 0; i <list.size(); i ++){if(2 == list.get(i)){list.remove(i); } system.out.println(list.get(i)); } system.out.println( "list =" + list.toString()); }出力結果:
1234LIST = [1、2、3、4]
質問:
結果は、1つの2つだけが削除され、他の2つが見逃されたことを示しています。その理由は、最初の2を削除した後、セット内の要素の数が1削減され、その後の要素が1ビットで移動され、2番目の2が見逃されます。
ループトラバーサルに使用する方法
例:
public static void listiterator2(){list <integer> list = new ArrayList <Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); for(int value:list){if(2 == value){list.remove(value); } system.out.println(value); } system.out.println(value); } system.out.println( "list =" + list.toString()); }結果:
java.util.arraylist $ ittr.checkforcomodification(unknown source)でjava.util.arraylist $ ittr.next(未知のソース)のスレッド「メイン」12java.util.concurrentmodificationexceptionの例外
説明:
jdkのconcurrentmodificationexceptionの説明:
public class ConcurrentModificationException extends
runtimeexceptionこの例外は、メソッドがオブジェクトの同時変更を検出するが、そのような変更を許可しない場合にスローされます。
たとえば、スレッドがコレクションを反復する場合、通常、別の線形変更を行うことはできません。通常、これらの場合、反復の結果は不確かです。この動作が検出された場合、一部のイテレーターの実装(JREが提供するすべての一般的なコレクション実装を含む)は、この例外をスローすることを選択できます。この操作を実行するイテレーターは、将来のある時点で任意の不確実な行動のリスクを危険にさらすことなく非常に迅速に失敗するため、高速障害反復剤と呼ばれます。
注:この例外は、オブジェクトが別のスレッドによって同時に変更されたことを常に示しているわけではありません。単一のスレッドがオブジェクトの契約に違反するメソッドコールのシーケンスを発行すると、オブジェクトはこの例外をスローする場合があります。たとえば、高速障害イテレーターを使用してコレクションを反復すると、スレッドがコレクションを直接変更する場合、イテレーターはこの例外をスローします。
注:繰り返しの速い故障動作は保証することはできません。なぜなら、一般的に、同期外の同時修正があるかどうかを難しい保証をすることは不可能であるからです。迅速な障害操作はConcurrentModificationExceptionを投げるために最善を尽くします。したがって、このような操作の正確性を改善するために、この例外に依存するプログラムを作成することは間違っています。正しい方法は次のとおりです。ConcurrentModificationException ConcurrentModificationException 、バグの検出にのみ使用する必要があります。
Javaのそれぞれについて、実際には処理にIteratorを使用します。 Iteratorでは、Iteratorの使用中にコレクションを削除することはできません。これにより、IteratorはConcurrentModificationExceptionをスローします。
正しい方法
例:
public static void listiterator3(){list <integer> list = new ArrayList <Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); iterator <integer> it = list.iterator(); while(it.hasnext()){integer value = it.next(); if(2 == value){it.remove(); } system.out.println(value); } system.out.println(value); } system.out.println( "list =" + list.toString()); }結果:
12234LIST = [1、3、4]
2。マップトラバーサル中に要素を削除します
正しいアプローチの例:
public static void main(string [] args){hashmap <string、string> map = new hashmap <string、string>(); map.put( "1"、 "test1"); map.put( "2"、 "test2"); map.put( "3"、 "test3"); map.put( "4"、 "test4"); //(entry <string、string> entry:map.entryset()){system.out.printf( "key:%s value:%s/r/n"、entry.getkey()、entry.getvalue()); } //要素iterator <map.entry <string、string >> it = map.entryset()。iterator(); while(it.hasnext()){map.entry <string、string> entry = it.next();文字列key = entry.getKey(); int k = integer.parseint(key); if(k%2 == 1){system.out.printf( "削除キー:%s値:%s/r/n"、key、entry.getvalue()); it.remove(); }} //(entry <string、string> entry:map.entryset()){system.out.printf( "key:%s値:%s/r/n"、entry.getkey()、entry.getvalue()); }}結果:
キー:1値:test1key:2値:test2key:3 value:test3key:4 value:test4deleteキー:1値:test1deleteキー:3値:test3key:test2key:4 value:test4
知らせ
しかし、 remove()のiteratorの方法について注意を払う必要があるものもあります。
remove() iterator.next() 。
remove()メソッドを呼び出す前に、 next()メソッドを1回呼び出す必要があります。
JDK-APIのremove()メソッドの説明:
void remove()イテレーターによって返された最後の要素を削除します。イテレーターが指すコレクション(オプション操作)を指し示します。この方法は、次に電話ごとに1回のみ呼び出すことができます。イテレーターが反復時にこのメソッドを呼び出す以外の方法で変更されている場合、イテレーターの動作はあいまいです。
スロー: UnsupportedOperationException iteratorが操作removeサポートしていない場合。 IllegalStateException nextメソッドが呼び出されていない場合、またはnextメソッドへの最後の呼び出し後にremoveメソッドが呼び出された場合。
要約します
上記は、リストとマップのトラバーサル中に要素を削除することです。この記事の内容が、すべての人の勉強や仕事に役立つことを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。