Javaでコレクションを学習するとき、コレクション階層ルートインターフェイスコレクションが、オブジェクトが「Foreach」ステートメントのターゲットになることを可能にするIterable <t>インターフェイス(Java.Langパッケージにある)を実装することが注目されます。このインターフェイスの唯一の方法は、T型要素のセットを反復するイテレーターを返すことです。
1。Iterator
インターフェイス:Iterator <T>
public interface iterator <e> {boolean hasnext(); e next(); void remove(); }Iterator Interface APIを見ると、これがコレクションを反復するイテレーターであることがわかります。イテレーターにより、発信者は、明確に定義されたセマンティクスを使用して、イテレーション中にイテレーターが指すコレクションから要素を削除できます。
このIterator remove()メソッドが使用されることは特に注目に値します。Iteratorによって返される最後の要素を削除して、イテレーターが指したコレクション(オプション操作)を指し示します。この方法は、次に電話ごとに1回のみ呼び出すことができます。イテレーターによって指されたコレクションが、反復時にこのメソッドを呼び出す以外の方法で変更された場合、イテレーターの動作は不確かです。 Iterator <t>インターフェイスを設計するとき、インターフェイスデザイナーは、反復時に、イテレーターを除くremove()メソッドが呼び出され、イテレーターによって指摘されたコレクションが変更されると、不確実な結果を引き起こすことを指摘しました。イテレーターの特定の実装に応じて、結果は何ですか。この不確実な結果の可能性のある状況に応じて、そのうちの1つは、ArrayListを学習するときに遭遇しました。Iteratorは、同時モジオ化の例外をスローします。特定の例外は、次のコードに示されています。
import java.util.arraylist; Import java.util.collection; import java.util.iterator; public class itaratortest {public static void main(string [] args){collection <string> list = new arraylist <string>(); list.add( "android"); list.add( "iOS"); list.add( "Windows Mobile"); iterator <string> iterator = list.iterator(); while(iterator.hasnext()){string lang = iterator.next(); list.remove(lang); //はconcurrentmodificationexception}}}}を投げますこのコードは、実行時にconcurrentModificationExceptionの例外をスローします。なぜなら、Iterator's Remove()メソッドを使用してIteratorの実行中に要素を削除するのではなく、代わりにArrayList's Remove()メソッドを使用して、iteratorが指すコレクションを変更します。これは、イテレーターの設計原則に違反するため、例外が発生します。
報告された異常は次のとおりです。
スレッド「Main」Java.util.concurrentModificationExceptionの例外
java.util.arraylist $ ittr.checkforcomodification(arraylist.java:859)
java.util.arraylist $ ittr.next(arraylist.java:831)
text.itaratortest.main(itaratortest.java:17)
2
Java 5から始まって、Javaには、コレクションと配列をループするために使用できます。 foreachループを使用すると、hasnext()メソッドを呼び出すことなくコレクションを通過せずに、whileループをループの従来のインデックスを保持せずに、またはiterator /listiterator(araylistでのイテレーター実装)を使用せずに通過できます。 for-for-forループは、任意のコレクションまたはアレイのトラバーサルプロセスを簡素化します。ただし、foreachループを使用する場合に注意を払うべき2つのポイントがあります。
foreachループを使用するオブジェクトは、反復可能な<t>インターフェイスを実装する必要があります
次の例をご覧ください。
import java.util.arraylist; public class foreachtest1 {public static void main(string args []){customcollection <string> myCollection = new CustomCollection <String>(); myCollection.Add( "Java"); myCollection.add( "scala"); myCollection.Add( "Groovy"); //このコードは何をしますか、言語を印刷し、例外をスローする、または//(文字列言語:myCollection){system.out.println(言語); }} private class customCollection <t> {private arraylist <t> bucket; public CustomCollection(){bucket = new arrayList(); } public int size(){return bucket.size(); } public boolean isempty(){return bucket.isempty(); } public boolean contains(t o){return bucket.contains(o); } public boolean add(t e){return bucket.add(e); } public boolean remove(t o){return bucket.remove(o); }}}コードのカスタムコレクションクラスが反復可能な<t>インターフェイスを実装しておらず、コンパイル期間中に報告されたエラーは次のとおりであるため、上記のコードはコンパイルされません。
スレッド「Main」Java.lang.Errorの例外:未解決のコンピレーションの問題:
java.lang.iterableの配列またはインスタンスを繰り返すことができます
at text.foreachtest1.main(foreachtest1.java:15)
実際、エラーを見つけるためにコンピレーションが始まるまで待つ必要はありません。 Eclipseは、コードが終了した後、foreachループにエラーを表示します。java.lang.iterableの配列またはインスタンスでのみ繰り返すことができます。
上記の例から、foreachループは、反復可能な<t>インターフェイスを実装するオブジェクトにのみ適用できることを再度確認できます。すべての組み込みのコレクションクラスは、java.util.collectionインターフェイスを実装し、繰り返し可能なため、上記の問題を解決するために、カスタムコレクションがコレクションインターフェイスを実装するか、抽象コレクションを継承できるようにすることを選択できます。解決策は次のとおりです。
Import java.util.abstractCollection; Import Java.util.arrayList; Import Java.util.iterator; public class foreachtest {public static void main(string args []){customCollection <string> myCollection = new CustomCollection <String>(); myCollection.Add( "Java"); myCollection.add( "scala"); myCollection.Add( "Groovy"); for(string言語:mycollection){system.out.println(言語); }} private static class customcollection <t> extends abstractCollection <t> {private arraylist <t> bucket; public CustomCollection(){bucket = new arrayList(); } public int size(){return bucket.size(); } public boolean isempty(){return bucket.isempty(); } public boolean contains(object o){return bucket.contains(o); } public boolean add(t e){return bucket.add(e); } public boolean remove(object o){return bucket.remove(o); } @Override public Iterator <t> iterator(){// todo auto-fenated method stub return bucket.iterator(); }}}2。foreachループの内部実装もIteratorによって実装されます。
foreachループが内部実装としてイテレータを使用しているという事実を確認するために、この記事の最初の例を使用して以下を確認します。
public class itaratortest {public static void main(string [] args){collection <string> list = new ArrayList <String>(); list.add( "android"); list.add( "iOS"); list.add( "Windows Mobile"); // example1 // iterator <string> iterator = list.iterator(); // while(iterator.hasnext()){// string lang = iterator.next(); // list.remove(lang); //} //例2 for(string言語:list){list.remove(言語); }}}プログラムが実行されたときに例外が報告されています:
スレッド「Main」Java.util.concurrentModificationExceptionの例外
java.util.arraylist $ ittr.checkforcomodification(arraylist.java:859)
java.util.arraylist $ ittr.next(arraylist.java:831)
text.itaratortest.main(itaratortest.java:22)
この例外は、for-eachループがイテレーターを使用してコレクションを繰り返すことを示しています。コレクションは、(要素)の変更をチェックして並行したexceptionをスローするiterator.next()を呼び出します。
要約:
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。