序文
Loopsの拡張を導入する理由:JDK5の以前のバージョンでは、配列の長さまたはコレクションのアレイまたはコレクションとイテレーターで要素を通過する方が面倒です。
新しい構文は、JDK5で定義されています - そのような操作を簡素化するためにループ用に拡張されています。拡張用ループは、反復可能なインターフェイスを実装する配列またはコレクションでのみ使用できます。
構文形式:
for(変数タイプ変数:繰り返す必要がある配列またはコレクション){
}
Javaでは、トラバースコレクションとアレイには一般に、次の3つのフォームがあります。
for(int i = 0; i <list.size(); i ++){system.out.print(list.get(i)+"、");} iterator iterator = list.iterator(); while(iterator.hasnext()){system.out.print(iterator.next() + "、");} for(integer i:list){system.out.print(i + "、");} 1つ目はループトラバーサルの場合は普通で、2つ目はトラバーサルにイテレータを使用することであり、3つ目は一般にループに対して拡張と呼ばれます(それぞれ)。
実装の原則
3番目のフォームはJavaが提供する構文糖であることがわかります。ここでは、この強化されたループが基礎となる層にどのように実装されるかを分析します。
次のコードを逆コンパイルします。
for(integer i:list){system.out.println(i);}逆コンパイル後:
integer i; for(iterator iterator = list.iterator(); iterator.hasnext(); system.out.println(i)){i =(integer)iterator.next(); }分解されたコードは実際には非常に複雑ですので、実行の順に分解しましょう。
整数I;一時的な変数iを定義します
iterator iterator = list.iterator();リストのiteratorを取得します
iterator.hasnext();イテレータに移動されていない要素があるかどうかを決定します
i =(integer)iterator.next();最初の移動のない要素を取得し、一時的な変数に割り当てますi
System.out.println(i)は、一時変数iの値を出力します
これは、リスト内のすべての要素が通過するまでサイクリングします。
逆コンパイルを通じて、Javaのループのために拡張された基礎となる層が実際にイテレーターパターンを通じて実装されていることがわかります。
forループを強化するピット
これはループの拡張のピットと言われていますが、実際には、主に一部の人々がループの拡張の実装原則のピットに足を踏み入れる可能性があるためです。
ループの拡張はイテレーターを介して実装されるため、イテレーターの特性が必要です。
Javaにはフェイルファーストメカニズムがあります。反復器を使用して要素を通過する場合、コレクションを削除するときは注意する必要があります。不適切に使用すると、ConcurrentModificationExceptionが発生する可能性があります。これはランタイムの例外であり、コンパイル期間中は発生しません。プログラムが実際に実行されているときにのみ爆発します。
次のコードのように:
for(学生STU:学生){if(stu.getid()== 2)sustent.remove(stu); }concurrentModificationException例外がスローされます。
Iteratorは別のスレッドで動作し、Mutex Lockがあります。イテレーターが作成された後、元のオブジェクトを指すシングルリンクインデックステーブル。元のオブジェクトの数が変更された場合、このインデックステーブルのコンテンツは同期して変更されないため、インデックスポインターが後方に移動すると、反復するオブジェクトが見つかりません。
java.util.concurrentModificationException例外。
したがって、イテレーターは、機能するときに反復オブジェクトを変更することを許可しません。
ただし、Iterator独自のメソッドremove()を使用して、オブジェクトを削除できます。 Iterator.remove()メソッドは、現在の繰り返しオブジェクトを削除しながら、インデックスの一貫性を維持します。
移動中に要素を正しく削除します。
Iterator <Student> Stuiter = sustent.iterator(); while(stuiter.hasnext()){desute desute = stuiter.next(); if(sustent.getid()== 2)stuiter.remove(); //ここで、イテレーターの削除方法を使用して現在のオブジェクトを削除する必要があります。リストの削除方法を使用すると、ConcurrentModificationExceptionも表示されます}わかりました、ここでは、不適切に使用した場合にforループを強化するという実装原則と、あなたが陥るかもしれない落とし穴を紹介します。したがって、それは単純な構文ですが、その原則も理解する必要があります。そうしないと、不可解な問題につながる可能性があります。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。