回答:
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
String item = i.next();
System.out.println(item);
}
i.remove();
ループで使用する必要がある場合、または何らかの方法で実際のイテレーターにアクセスする必要がある場合for ( : )
、実際のイテレーターは推定されるだけなので、イディオムを使用できないことに注意してください。
Denis Buenoが述べたように、このコードは、Iterable
インターフェイスを実装するすべてのオブジェクトに対して機能します。
また、for (:)
イディオムの右側がオブジェクトではarray
なくIterable
オブジェクトである場合、内部コードはintインデックスカウンターを使用し、array.length
代わりにチェックします。Java言語仕様を参照してください。
import java.util.Iterator;
およびimport java.lang.Iterable;
java.util.Iterator
して実装しないIterable
のでできませんfor(String s : (Iterator<String>)foo)
。これは、なぜ私が理解し、それがされて刺激します。
構文それぞれのは、また、アレイに対して有効です。例えば
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };
for (String fruit : fruits) {
// fruit is an element of the `fruits` array.
}
これは基本的に
for (int i = 0; i < fruits.length; i++) {
String fruit = fruits[i];
// fruit is an element of the `fruits` array.
}
したがって、全体的な要約:
[nsayer]以下は、発生していることの長い形式です。
for(Iterator<String> i = someList.iterator(); i.hasNext(); ) { String item = i.next(); System.out.println(item); }
i.remove();を使用する必要がある場合は注意してください。ループ内、または実際のイテレータに何らかの方法でアクセスする場合、for(:)イディオムは使用できません。
それはnsayerの答えによって暗示されていますが、「someList」がjava.lang.Iterableを実装するものである場合、OPのfor(..)構文が機能することは注目に値します-リストまたはいくつかのコレクションである必要はありませんjava.util。したがって、独自の型でもこの構文で使用できます。
foreach
ループに追加、Java 5のは、(また、「拡張forループ」と呼ばれる)使用するのと同じですjava.util.Iterator
同じもののために--itのシンタックスシュガーを。したがって、各要素を1つずつ順番に読み取ると、foreach
、より便利で簡潔になる常に反復子よりもを選択必要があります。
for(int i : intList) {
System.out.println("An element in the list: " + i);
}
Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
System.out.println("An element in the list: " + intItr.next());
}
Iterator
直接使用する必要がある状況があります。たとえば、foreach
缶を使用しているときに要素を削除しようとすると(する?)、結果はになりConcurrentModificationException
ます。
foreach
対for
:基本的な違いとの唯一の実用的な違いはfor
、foreach
インデックス付け可能なオブジェクトの場合、インデックスにアクセスできないことです。基本的な場合の例for
ループが必要:
for(int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
手動で別のインデックスint-variableを作成することもできますが foreach
、
int idx = -1;
for(int i : intArray) {
idx++;
...
}
変数スコープなので、お勧めしませんは理想的ではなく、基本的なfor
ループはこのユースケースの単なる標準で予期される形式であるため。
foreach
対 for
:パフォーマンスコレクションにアクセスするとき、a foreach
はかなり高速です基本for
ループの配列アクセスもです。ただし、配列にアクセスする場合、少なくともプリミティブ配列とラッパー配列を使用すると、インデックスを介したアクセスが劇的に速くなります。
インデックスは23-にある40アクセスする際のイテレータよりも速くパーセントint
またはInteger
配列。これは、この投稿の下部にあるテストクラスからの出力で、100要素のプリミティブ整数配列(Aはイテレータ、Bはインデックス)の数値を合計しています。
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 358,597,622 nanoseconds
Test B: 269,167,681 nanoseconds
B faster by 89,429,941 nanoseconds (24.438799231635727% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 377,461,823 nanoseconds
Test B: 278,694,271 nanoseconds
B faster by 98,767,552 nanoseconds (25.666236154695838% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 288,953,495 nanoseconds
Test B: 207,050,523 nanoseconds
B faster by 81,902,972 nanoseconds (27.844689860906513% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,373,765 nanoseconds
Test B: 283,813,875 nanoseconds
B faster by 91,559,890 nanoseconds (23.891659337194227% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,790,818 nanoseconds
Test B: 220,770,915 nanoseconds
B faster by 155,019,903 nanoseconds (40.75164734599769% faster)
[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 326,373,762 nanoseconds
Test B: 202,555,566 nanoseconds
B faster by 123,818,196 nanoseconds (37.437545972215744% faster)
私はこれもInteger
配列に対して実行しましたが、インデックスは依然として明らかな勝者ですが、18から25%だけ高速です。
以下のためList
のIntegers
、しかし、イテレータは明確な勝者です。test-classのint-arrayを次のように変更するだけです。
List<Integer> intList = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100});
そして、テスト関数に必要な変更を加えます(int[]
to List<Integer>
、length
to size()
など):
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,429,929,976 nanoseconds
Test B: 5,262,782,488 nanoseconds
A faster by 1,832,852,512 nanoseconds (34.326681820485675% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,907,391,427 nanoseconds
Test B: 3,957,718,459 nanoseconds
A faster by 1,050,327,032 nanoseconds (26.038700083921256% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,566,004,688 nanoseconds
Test B: 4,221,746,521 nanoseconds
A faster by 1,655,741,833 nanoseconds (38.71935684115413% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,770,945,276 nanoseconds
Test B: 3,829,077,158 nanoseconds
A faster by 1,058,131,882 nanoseconds (27.134122749113843% faster)
[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,467,474,055 nanoseconds
Test B: 5,183,149,104 nanoseconds
A faster by 1,715,675,049 nanoseconds (32.60101667104192% faster)
[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,439,983,933 nanoseconds
Test B: 3,509,530,312 nanoseconds
A faster by 69,546,379 nanoseconds (1.4816434912159906% faster)
[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,451,101,466 nanoseconds
Test B: 5,057,979,210 nanoseconds
A faster by 1,606,877,744 nanoseconds (31.269164666060377% faster)
1つのテストではそれらはほぼ同等ですが、コレクションではイテレータが優先されます。
*この投稿は、Stack Overflowで書いた2つの回答に基づいています。
もう少し情報:for-eachループとイテレーターのどちらがより効率的ですか?
Stack Overflowでこの質問を読んだ後、私はこの比較時間の取り方と実行する2つのことのクラスを作成しました。
import java.text.NumberFormat;
import java.util.Locale;
/**
<P>{@code java TimeIteratorVsIndexIntArray 1000000}</P>
@see <CODE><A HREF="/programming/180158/how-do-i-time-a-methods-execution-in-java">/programming/180158/how-do-i-time-a-methods-execution-in-java</A></CODE>
**/
public class TimeIteratorVsIndexIntArray {
public static final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
public static final void main(String[] tryCount_inParamIdx0) {
int testCount;
// Get try-count from a command-line parameter
try {
testCount = Integer.parseInt(tryCount_inParamIdx0[0]);
}
catch(ArrayIndexOutOfBoundsException | NumberFormatException x) {
throw new IllegalArgumentException("Missing or invalid command line parameter: The number of testCount for each test. " + x);
}
//Test proper...START
int[] intArray = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100};
long lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testIterator(intArray);
}
long lADuration = outputGetNanoDuration("A", lStart);
lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testFor(intArray);
}
long lBDuration = outputGetNanoDuration("B", lStart);
outputGetABTestNanoDifference(lADuration, lBDuration, "A", "B");
}
private static final void testIterator(int[] int_array) {
int total = 0;
for(int i = 0; i < int_array.length; i++) {
total += int_array[i];
}
}
private static final void testFor(int[] int_array) {
int total = 0;
for(int i : int_array) {
total += i;
}
}
//Test proper...END
//Timer testing utilities...START
public static final long outputGetNanoDuration(String s_testName, long l_nanoStart) {
long lDuration = System.nanoTime() - l_nanoStart;
System.out.println("Test " + s_testName + ": " + nf.format(lDuration) + " nanoseconds");
return lDuration;
}
public static final long outputGetABTestNanoDifference(long l_aDuration, long l_bDuration, String s_aTestName, String s_bTestName) {
long lDiff = -1;
double dPct = -1.0;
String sFaster = null;
if(l_aDuration > l_bDuration) {
lDiff = l_aDuration - l_bDuration;
dPct = 100.00 - (l_bDuration * 100.0 / l_aDuration + 0.5);
sFaster = "B";
}
else {
lDiff = l_bDuration - l_aDuration;
dPct = 100.00 - (l_aDuration * 100.0 / l_bDuration + 0.5);
sFaster = "A";
}
System.out.println(sFaster + " faster by " + nf.format(lDiff) + " nanoseconds (" + dPct + "% faster)");
return lDiff;
}
//Timer testing utilities...END
}
for(int value : int_array) {/* loop content */}
ことは構文的に同等であるので、あなたのテストで最も遅いfor(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}
テストを比較するものではありませんこれは、。
int value = int_array[i];
ための最初にループの場合は、foreachを使用することもできます。何らかの理由でインデックスへのアクセスも必要でない限り、簡単に言うと、すべてがコンテキストに依存します。)
これは、Javaイテレータの知識を前提としない回答です。精度は落ちますが、教育には役立ちます。
プログラミング中、私たちはしばしば次のようなコードを書きます。
char[] grades = ....
for(int i = 0; i < grades.length; i++) { // for i goes from 0 to grades.length
System.out.print(grades[i]); // Print grades[i]
}
foreach構文により、この一般的なパターンをより自然で構文的にノイズの少ない方法で記述できます。
for(char grade : grades) { // foreach grade in grades
System.out.print(grade); // print that grade
}
さらに、この構文は、配列のインデックス作成をサポートしないが、Java Iterableインターフェースを実装するリストやセットなどのオブジェクトに有効です。
それはnsayerの答えによって暗示されていますが、「someList」がjava.lang.Iterableを実装するものである場合、OPのfor(..)構文が機能することは注目に値します-リストまたはいくつかのコレクションである必要はありませんjava.util。したがって、独自のタイプでもこの構文で使用できます。
JLSで定義されているように、for-eachループには次の2つの形式があります。
式のタイプがのサブタイプであるIterable
場合、変換は次のようになります。
List<String> someList = new ArrayList<String>();
someList.add("Apple");
someList.add("Ball");
for (String item : someList) {
System.out.println(item);
}
// IS TRANSLATED TO:
for(Iterator<String> stringIterator = someList.iterator(); stringIterator.hasNext(); ) {
String item = stringIterator.next();
System.out.println(item);
}
式の配列型が必須の場合T[]
:
String[] someArray = new String[2];
someArray[0] = "Apple";
someArray[1] = "Ball";
for(String item2 : someArray) {
System.out.println(item2);
}
// IS TRANSLATED TO:
for (int i = 0; i < someArray.length; i++) {
String item2 = someArray[i];
System.out.println(item2);
}
Java 8では、一般的にパフォーマンスの高いストリームが導入されています。これらは次のように使用できます。
someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
foreachループ構文は次のとおりです。
for (type obj:array) {...}
例:
String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
System.out.println(str);
}
出力:
Java
Coffe
Is
Cool
警告:foreachループで配列要素にアクセスできますが、初期化することはできません。そのために元のfor
ループを使用します。
警告:配列のタイプを他のオブジェクトと一致させる必要があります。
for (double b:s) // Invalid-double is not String
要素を編集する場合は、次のfor
ような元のループを使用します。
for (int i = 0; i < s.length-1 /*-1 because of the 0 index */; i++) {
if (i==1) //1 because once again I say the 0 index
s[i]="2 is cool";
else
s[i] = "hello";
}
sをコンソールにダンプすると、次のようになります。
hello
2 is cool
hello
hello
ウィキペディアで言及されているforeachループの概念を以下に示します。
ただし、他のforループ構造とは異なり、foreachループは通常、明示的なカウンターを維持しません。つまり、「これをx回実行する」ではなく、「このセットのすべてに対してこれを実行する」と本質的に言います。これにより、潜在的なオフバイワンエラーが回避され、コードが読みやすくなります。
したがって、foreachループの概念は、ループが明示的なカウンターを使用しないことを示しています。つまり、リストをトラバースするためにインデックスを使用する必要がないため、ユーザーを1つずつのエラーから節約できます。この1つずれたエラーの一般的な概念を説明するために、インデックスを使用してリスト内をトラバースするループの例を見てみましょう。
// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){
}
ただし、リストがインデックス1で始まる場合、インデックス0に要素が見つからないため、このループは例外をスローし、このエラーは1つずれるエラーと呼ばれます。したがって、この1つずれたエラーを回避するために、foreachループの概念が使用されます。他にも利点があるかもしれませんが、これが、foreachループを使用することの主な概念と利点だと私が思うものです。
Java 8では、forEachが導入されました。リストを使用すると、マップをループできます。
for eachを使用してリストをループする
List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");
someList.forEach(listItem -> System.out.println(listItem))
または
someList.forEach(listItem-> {
System.out.println(listItem);
});
for eachを使用してマップをループする
Map<String, String> mapList = new HashMap<>();
mapList.put("Key1", "Value1");
mapList.put("Key2", "Value2");
mapList.put("Key3", "Value3");
mapList.forEach((key,value)->System.out.println("Key: " + key + " Value : " + value));
または
mapList.forEach((key,value)->{
System.out.println("Key : " + key + " Value : " + value);
});
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
String item = itr.next();
System.out.println(item);
}
古いバージョンのJava Java 7
を使用foreach
すると、次のようにループを使用できます。
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
for(String item : items){
System.out.println(item);
}
以下はforeach
ループインを使用する最新の方法ですJava 8
(forEach
+ラムダ式またはメソッド参照でリストをループします)
//lambda
//Output : A,B,C,D,E
items.forEach(item->System.out.println(item));
//method reference
//Output : A,B,C,D,E
items.forEach(System.out::println);
詳細については、このリンクを参照してください。
また、元の質問で「foreach」メソッドを使用すると、反復中にリストから項目を削除できないなど、いくつかの制限があることに注意してください。
新しいforループは読みやすく、個別のイテレーターが不要になりますが、実際には読み取り専用の反復パスでのみ使用できます。
removeIf
適切なツールになる可能性があります
「for each」を回避するためのforEachの代替:
List<String> someList = new ArrayList<String>();
バリエーション1(プレーン):
someList.stream().forEach(listItem -> {
System.out.println(listItem);
});
バリアント2(並列実行(高速)):
someList.parallelStream().forEach(listItem -> {
System.out.println(listItem);
});
for(
同じスレッドが使用されていることを確認したい場合は、フォームを使用します。マルチスレッドでの実行を許可する場合は、ストリーム形式を使用します。
基本的なループクラッタをすべて取り除くことで、コードに美しさを追加します。これにより、コードをきれいに見せることができます。
通常のfor
ループ:
void cancelAll(Collection<TimerTask> list) {
for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
i.next().cancel();
}
for-eachの使用:
void cancelAll(Collection<TimerTask> list) {
for (TimerTask t : list)
t.cancel();
}
for-eachは、Iteratorを実装するコレクションの構造です。コレクションはIteratorを実装する必要があることに注意してください。それ以外の場合、for-eachでは使用できません。
次の行では「と読まれ、リスト内の各TimerTaskをtのために。」
for (TimerTask t : list)
for-eachの場合、エラーの可能性は低くなります。イテレータを初期化したり、ループカウンターを初期化して終了したりする必要はありません(エラーの余地がある場合)。
Java 8より前は、次のものを使用する必要があります。
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
ただし、Java 8でのStreamsの導入により、はるかに少ない構文で同じことを行うことができます。たとえば、あなたのためにあなたがsomeList
することができます:
someList.stream().forEach(System.out::println);
ストリームについて詳しくは、こちらをご覧ください。
The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
こんな感じになります。非常に無愛想です。
for (Iterator<String> i = someList.iterator(); i.hasNext(); )
System.out.println(i.next());
Sunのドキュメントには、それぞれについて適切な説明があります。
非常に多くの良い答えが言ったように、オブジェクトIterable interface
を使用する場合、オブジェクトはfor-each
ループます。
簡単な例を投稿して、for-each
ループがどのように機能するかを別の方法で説明します。
for-each
ループの例:
public class ForEachTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("111");
list.add("222");
for (String str : list) {
System.out.println(str);
}
}
}
次に、javap
このクラスを逆コンパイルするために使用すると、次のバイトコードサンプルが取得されます。
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: new #16 // class java/util/ArrayList
3: dup
4: invokespecial #18 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #19 // String 111
11: invokeinterface #21, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: aload_1
18: ldc #27 // String 222
20: invokeinterface #21, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
25: pop
26: aload_1
27: invokeinterface #29, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
サンプルの最後の行からわかるように、コンパイラーはfor-each
キーワードの使用をIterator
コンパイル時の使用に自動的に変換します。これは、を実装していないオブジェクトがループを使用しようとしIterable interface
たException
ときにをスローする理由を説明している可能性がありfor-each
ます。
各ループのJava(別名拡張forループ)は、forループの簡略化したバージョンです。利点は、記述するコードが少なく、管理する変数が少ないことです。欠点は、ステップ値を制御できず、ループ本体内のループインデックスにアクセスできないことです。
これらは、ステップ値が1の単純な増分であり、現在のループ要素へのアクセスのみが必要な場合に最適です。たとえば、現在の要素の前後を覗くことなく、配列またはコレクションのすべての要素をループする必要がある場合などです。
ループの初期化、ブール条件はなく、ステップ値は暗黙的であり、単純な増分です。これが、通常のforループよりもはるかに単純であると考えられている理由です。
拡張forループは、次の実行順序に従います。
1)ループ本体
2)アレイ全体またはコレクション全体がトラバースされるまで、手順1から繰り返します
例–整数配列
int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
System.out.println(currentValue);
}
currentValue変数は、ループされている現在の値をintArray配列に保持します。明示的なステップ値がないことに注意してください。これは常に1ずつ増加します。
コロンは「中」を意味すると考えることができます。つまり、拡張されたforループ宣言では、intArrayをループし、現在の配列のint値を currentValue変数に格納します。
出力:
1
3
5
7
9
例–文字列配列
for-eachループを使用して、文字列の配列を反復処理できます。ループ宣言では、myStrings文字列配列をループして、現在の文字列値を currentString変数に格納します。
String [] myStrings = {
"alpha",
"beta",
"gamma",
"delta"
};
for(String currentString : myStrings) {
System.out.println(currentString);
}
出力:
alpha
beta
gamma
delta
例–リスト
拡張されたforループを使用して、次のようにjava.util.Listを反復することもできます。
List<String> myList = new ArrayList<String>();
myList.add("alpha");
myList.add("beta");
myList.add("gamma");
myList.add("delta");
for(String currentItem : myList) {
System.out.println(currentItem);
}
ループ宣言では、myList List of Stringsにループし、現在のList値を格納します。 currentItem変数にます。
出力:
alpha
beta
gamma
delta
例–セット
拡張されたforループを使用して、次のようにjava.util.Setを反復することもできます。
Set<String> mySet = new HashSet<String>();
mySet.add("alpha");
mySet.add("alpha");
mySet.add("beta");
mySet.add("gamma");
mySet.add("gamma");
mySet.add("delta");
for(String currentItem : mySet) {
System.out.println(currentItem);
}
ループ宣言では、mySet文字列のセットをループし、現在のセット値を currentItem変数に格納します。これはセットであるため、重複する文字列値は保存されないことに注意してください。
出力:
alpha
delta
beta
gamma
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
for(int k=0;k<totalsize;k++)
{
fullst.addAll();
}
}
Javaのfor-eachイディオムは、* Iterableタイプの配列またはオブジェクトにのみ適用できます。このイディオムは、イテレーターによって本当に裏付けられているため、暗黙的です。イテレーターはプログラマーによってプログラムされ、多くの場合、その位置を追跡するために整数のインデックスまたはノード(データ構造に応じて)を使用します。紙の上では、通常のforループよりも遅く、少なくとも配列やリストなどの「線形」構造では遅くなりますが、より抽象化されています。
これはクレイジーに見えますが、ちょっとそれはうまくいきます
List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);
これは機能します。マジック
他の多くの答えが正しく述べているように、これfor
each
loop
は同じ古いものに対する構文上の砂糖でfor
loop
あり、コンパイラはそれを同じ古いforループに変換します。
javac(open jdk)にはswitch -XD-printflat
があり、すべての構文糖が削除されたjavaファイルが生成されます。完全なコマンドは次のようになります
javac -XD-printflat -d src/ MyFile.java
//-d is used to specify the directory for output java file
この質問に答えるために、私は、ファイルを作成したとの2つのバージョンを書いたfor
each
、との1 array
とし、別のlist
。私のjava
ファイルはこのように見えました。
import java.util.*;
public class Temp{
private static void forEachArray(){
int[] arr = new int[]{1,2,3,4,5};
for(int i: arr){
System.out.print(i);
}
}
private static void forEachList(){
List<Integer> list = Arrays.asList(1,2,3,4,5);
for(Integer i: list){
System.out.print(i);
}
}
}
私は、ときにcompiled
上記スイッチを使用してこのファイルを、私は次の出力を得ました。
import java.util.*;
public class Temp {
public Temp() {
super();
}
private static void forEachArray() {
int[] arr = new int[]{1, 2, 3, 4, 5};
for (/*synthetic*/ int[] arr$ = arr, len$ = arr$.length, i$ = 0; i$ < len$; ++i$) {
int i = arr$[i$];
{
System.out.print(i);
}
}
}
private static void forEachList() {
List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5)});
for (/*synthetic*/ Iterator i$ = list.iterator(); i$.hasNext(); ) {
Integer i = (Integer)i$.next();
{
System.out.print(i);
}
}
}
}
各ループの他の構文糖(オートボクシング)とともに単純なループに変更されていることがわかります。
List<Item> Items = obj.getItems();
for(Item item:Items)
{
System.out.println(item);
}
Itemsテーブルのすべてのオブジェクトを反復処理します。