Java 'for each'루프는 어떻게 작동합니까?


1498

치다:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
    System.out.println(item);
}

구문 에 대해for 를 사용하지 않고 동등한 루프는 어떻게 생겼 습니까?


: JLS에 따라이 두 가지 형태가 stackoverflow.com/a/33232565/1216775
akhil_mittal

답변:


1175
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
    String item = i.next();
    System.out.println(item);
}

i.remove();루프에서 사용하거나 실제 반복자에 어떤 방식으로 액세스 해야하는 경우 for ( : )실제 반복자가 유추되기 때문에 관용구를 사용할 수 없습니다 .

Denis Bueno가 언급했듯이이 코드는 Iterable인터페이스 를 구현하는 모든 객체에서 작동합니다 .

또한 for (:)관용구 의 오른쪽 arrayIterable객체 가 아닌 경우 내부 코드는 int 인덱스 카운터를 사용하고 array.length대신 검사 합니다. Java 언어 사양을 참조하십시오 .


14
while (someList.hasMoreElements ()) {// do something}} 과 같이 while 루프를 호출하는 것을 발견했습니다.이 질문을 검색 할 때 찾고 싶었던 코딩 은혜에 가깝습니다.
제임스 T 스넬

6
또한 foreach 루프를 설명하는 docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html 을 참조하십시오 (소개 될 때)
PhoneixS

1
안드로이드 스튜디오 개발자 : import java.util.Iterator;import java.lang.Iterable;
dsdsdsdsd

실망스럽게도 java.util.Iterator구현할 Iterable수 없으므로 구현할 수 없습니다 for(String s : (Iterator<String>)foo). 나는이 이유를 이해하지만, 그것은 됩니다 자극적입니다.
Christopher Schultz '10

499

각각 의 구문 배열에도 유효합니다. 예 :

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. 따라서 자신의 유형조차도이 구문과 함께 사용할 수 있습니다.


161

foreach루프 추가, 자바 (5) , (또한 "향상된 루프"라고 함)을 사용하는 것과 같습니다 java.util.Iterator같은 일에 대한 --it의 문법 설탕을. 따라서 각 요소를 하나씩 순서대로 읽을 때 foreach더 편리하고 간결하므로 반복자에서 항상 a 를 선택해야합니다.

각각

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직접 사용해야하는 상황이 있습니다. 예를 들어, foreachcan (will?) 을 사용하는 동안 요소를 삭제하려고하면 결과가 나타납니다 ConcurrentModificationException.

foreachvs. for: 기본 차이점

의 유일한 실제적인 차이 forforeach색인 오브젝트의 경우, 인덱스에 액세스 할 수없는 그이다. 기본 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++;
   ...
}

variable-scope 가 이상적이지 않으므로 기본 for루프는이 유스 케이스에 대한 표준적이고 예상되는 형식 일 뿐이 므로 권장 되지 않습니다 .

foreachvs. for: 성능

컬렉션에 액세스 할 때 a foreach는 기본 루프의 어레이 액세스 보다 훨씬 빠릅니다for . 그러나 적어도 기본 및 랩퍼 배열을 사용하여 배열에 액세스하면 인덱스를 통한 액세스가 훨씬 빠릅니다.

기본 int- 배열에 대한 반복자와 인덱스 액세스의 차이 타이밍

인덱스는 23-이다 (40) 에 액세스 할 때 반복자 % 이상 빠르게 int또는 Integer배열. 이 게시물의 맨 아래에있는 테스트 클래스의 출력은 100 요소 primitive-int 배열의 숫자를 합칩니다 (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 % 더 빠릅니다.

컬렉션의 경우 반복자는 인덱스보다 빠릅니다.

A의 ListIntegers, 그러나, 반복자는 확실한 승자입니다. 테스트 클래스에서 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[]하는 List<Integer>, lengthsize(), 등)

[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)

한 번의 테스트에서는 거의 동일하지만 컬렉션을 사용하면 반복자가 승리합니다.

*이 게시물은 내가 스택 오버플로에 쓴 두 가지 답변을 기반으로합니다.

더 많은 정보 : 어느 것이 더 효율적인지, for-each 루프 또는 반복자입니까?

전체 테스트 클래스

Stack Overflow 에서이 질문 을 읽은 후이 시간 비교와 할일을 비교하는 클래스를 만들었습니다 .

import  java.text.NumberFormat;
import  java.util.Locale;

/**
   &lt;P&gt;{@code java TimeIteratorVsIndexIntArray 1000000}&lt;/P&gt;

   @see  &lt;CODE&gt;&lt;A HREF=&quot;/programming/180158/how-do-i-time-a-methods-execution-in-java&quot;&gt;/programming/180158/how-do-i-time-a-methods-execution-in-java&lt;/A&gt;&lt;/CODE&gt;
 **/
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

}

4
이 답변은 이제 블로그 게시물 이며 내가 작성한 두 가지 관련 답변 : herehere에서 작성 되었습니다 . 또한 두 기능의 속도를 비교할 때 일반적으로 유용한 클래스가 포함되어 있습니다 (하단).
aliteralmind

1
여기에 단지 하나의 사소한 의견 만 있다면, 컬렉션에 액세스하는 데 항상 for (:) 구문이 더 낫다고 범주 적으로 언급해서는 안됩니다. 배열 목록을 사용하는 경우 for (:) 루프는 for (int i = 0, len = arrayList.size (); i <len; i ++)를 사용하는 것보다 약 2 배 느립니다. 어쨌든 [link] ( stackoverflow.com/questions/2113216/… ) 링크 에서 언급 했지만, 강조 표시하는 것이 중요합니다 ...
Leo

@Leo 좋은 지적입니다. ArrayList는 Collection이지만 배열에 의해 지원되므로 일반 표준이 더 좋습니다.
aliteralmind

나는 for(int value : int_array) {/* loop content */}그것이 구문 적으로 동등하기 때문에 테스트에서 가장 느리다고 생각합니다 for(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}. 이것은 테스트와 비교되지 않습니다.
daiscog

(그런데, 당신의 검사가 잘못 말하는 게 아니에요,하지만 사람들이 특정 시나리오에 대한 옳은 일을 선택할 수 있도록 차이 뒤에 이유를 지적 가치가있을 수도 있습니다. 그들이 일을하는 경우 int value = int_array[i];자신에 대한의 시작 루프를 사용하면 foreach를 사용할 수도 있습니다. 어떤 이유로 든 인덱스에 액세스해야하는 경우가 아니면 문맥에 따라 다릅니다.)
daiscog

129

다음은 Java Iterators에 대한 지식이없는 답변입니다. 덜 정확하지만 교육에 유용합니다.

프로그래밍하는 동안 종종 다음과 같은 코드를 작성합니다.

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 인터페이스를 구현하는 목록 또는 세트와 같은 오브젝트에 유효합니다.


40

Java의 for-each 루프는 기본 반복자 메커니즘을 사용합니다. 따라서 다음과 동일합니다.

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
  String item = iterator.next();
  System.out.println(item);
}

25

Java 8 기능에서는 다음을 사용할 수 있습니다.

List<String> messages = Arrays.asList("First", "Second", "Third");

void forTest(){
    messages.forEach(System.out::println);
}

산출

First
Second
Third

7
이 임의의 정보는 원격으로 질문에 대답하지도 않습니다
Tim

25

그것은 nsayer의 대답에 의해 암시,하지만 "someList"이 때 OP가 있다고 지적 그것의 가치는 (..) 구문 작동합니다 아무것도 구현 java.lang.Iterable가 -가 목록 또는 일부 컬렉션에서 일 필요는 없습니다가 java.util. 따라서 자신의 유형조차도이 구문과 함께 사용할 수 있습니다.


1
fd is right-for (:) 관용구의 오른쪽에서 반복자를 가져 오는 대신 int 및 array.length를 사용하는 경우의 내부 코드입니다. forums.sun.com/thread.jspa?messageID=2743233
nsayer

24

JLS for-each 루프에 정의 된대로 두 가지 형식을 가질 수 있습니다.

  1. Expression 유형이 하위 유형 인 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);
    }
  2. Expression에 반드시 배열 유형이있는 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);

2
가장 적절하고 정확한 답변. 마법에 걸린 것은 실제로 두 가지 번역이 있습니다.
Zarial

23

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

21

Java "for-each"루프 구문을 사용하면 두 가지 유형의 객체를 반복 할 수 있습니다.

  • T[] (모든 유형의 배열)
  • java.lang.Iterable<T>

Iterable<T>인터페이스는 하나의 방법이 있습니다 Iterator<T> iterator(). 인터페이스가 확장 Collection<T>되기 때문에 유형의 객체에서 작동합니다 .Collection<T>Iterable<T>


16

Wikipedia에 언급 된 foreach 루프의 개념은 다음과 같습니다.

그러나 다른 for 루프 구문과 달리 foreach 루프는 일반적으로 명시적인 카운터를 유지 하지 않습니다 . 기본적으로 "이 작업을 x 번 수행하는 대신"이 세트의 모든 작업에 수행 "이라고 말합니다. 따라서 잠재적 인 오류가 발생하지 않으며 코드를보다 쉽게 ​​읽을 수 있습니다.

따라서 foreach 루프의 개념은 루프가 명시 적 카운터를 사용하지 않는다는 것을 설명합니다. 즉, 목록에서 순회하기 위해 인덱스를 사용할 필요가 없으므로 사용자가 일대일 오류를 방지 할 수 있습니다. 이 일대일 오류의 일반적인 개념을 설명하기 위해 인덱스를 사용하여 목록에서 순회하는 루프의 예를 보자.

// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){

}

그러나 목록이 인덱스 1로 시작하면 인덱스 0에서 요소를 찾을 수 없으므로이 루프에서 예외가 발생한다고 가정하고이 오류를 일대일 오류라고합니다. 따라서이 개별 오류를 피하기 위해 foreach 루프의 개념이 사용됩니다. 다른 장점도있을 수 있지만 이것이 foreach 루프를 사용하는 주요 개념 및 장점이라고 생각합니다.


13

Java 8에서는 각각을 소개했습니다. 목록을 사용하여지도를 반복 할 수 있습니다.

각각을 사용하여 목록 반복

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); 
});

각각을 사용하여 맵 반복

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);
});

12
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}

11

이전 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+ 람다 식 또는 메서드 참조 로 List를 반복 )

//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);

자세한 내용은이 링크를 참조하십시오.

https://www.mkyong.com/java8/java-8-foreach-examples/


10

동등한 표현이 있습니다.

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}

10

또한 원래 질문에서 "foreach"방법을 사용하면 반복 중에 목록에서 항목을 제거 할 수없는 것과 같은 일부 제한이 있습니다.

새로운 for-loop는 읽기 쉽고 별도의 반복자가 필요하지 않지만 읽기 전용 반복 단계에서만 실제로 사용할 수 있습니다.


1
이 경우 removeIf올바른 도구를 사용해야 합니다.
ncmathsadist

9

"각"을 피하기위한 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);
});

2
Java 1.8
TheLibrarian

동일한 스레드가 사용되었다고 100 % 확신 할 수 없습니다. for(동일한 스레드가 사용되도록 하려면 양식 을 사용하고 싶습니다. 멀티 스레드 실행을 허용하려면 스트림 형식을 사용하고 싶습니다.
Grim

8

기본 루핑 혼란을 모두 제거하여 코드에 아름다움을 더합니다. 아래에 정당한 코드를 깔끔하게 보여줍니다.

정규 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-eachIterator 를 구현하는 컬렉션에 대한 구성 입니다. 컬렉션은 Iterator 를 구현해야합니다 . 그렇지 않으면 for-each와 함께 사용할 수 없습니다.

다음 줄은 목록의 각 TimerTask t에 대해 " 로 표시됩니다. "

for (TimerTask t : list)

for-each의 경우 오류가 발생할 가능성이 줄어 듭니다. 반복자를 초기화하거나 루프 카운터를 초기화하고 종료하는 것에 대해 걱정할 필요가 없습니다 (오류 범위가있는 경우).


8

Java 8 이전에는 다음을 사용해야합니다.

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
}

그러나 Java 8에서 스트림을 도입하면 훨씬 적은 구문으로 동일한 작업을 수행 할 수 있습니다. 예를 들어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
Alex78191

7

이런 식으로 보일 것입니다. 매우 잔인합니다.

for (Iterator<String> i = someList.iterator(); i.hasNext(); )
        System.out.println(i.next());

Sun 문서 에는 각각 좋은 글이 있습니다 .


6

많은 좋은 답변이 말했듯이 객체는 루프 Iterable interface를 사용 하려면 if 를 구현해야합니다 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를 던질 이유를 설명 할 수 있습니다 .Exceptionfor-each


6

각 루프에 대한 자바 (일명 향상된 루프)는 루프 (A)의 간략화 된 버전이다. 장점은 작성할 코드가 적고 관리 할 변수가 적다는 것입니다. 단점은 단계 값을 제어 할 수없고 루프 본체 내부의 루프 인덱스에 액세스 할 수 없다는 것입니다.

단계 값이 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 String 배열을 루프하고 현재 문자열 값 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 변수 저장합니다 . 이것이 Set이므로 중복 문자열 값은 저장되지 않습니다.

산출:

alpha
delta
beta
gamma

출처 : Java의 루프 – Ultimate Guide


4
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
            for(int k=0;k<totalsize;k++)
            {
              fullst.addAll();
            }
}

3

Java for-each 관용구는 * Iterable 유형의 배열 또는 객체에만 적용 할 수 있습니다 . 이 관용구는 Iterator가 진정으로 뒷받침하므로 암시 적 입니다. 반복자는 프로그래머에 의해 프로그래밍되며 종종 데이터 구조에 따라 정수 인덱스 또는 노드를 사용하여 위치를 추적합니다. 종이에서는 보통 for-loop보다 느리고, 배열 및 목록과 같은 "선형"구조에서는 느리지 만 더 큰 추상화를 제공합니다.


-1 : 이것은 읽기 쉽지 않은 (일반적으로) : 자신의 예제 (첫 번째 예제)조차도 배열의 첫 번째 요소를 제외하기 때문에 잘못되었습니다.
Ondrej Skopek

2

이건 미쳐 보이지만 이봐

List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);

작동합니다. 마법


1
이를 위해서는 Java 1.8 +
BARNI

2
원격으로 질문에 대답하지 않습니다
Tim

2

다른 많은 답변들이 올바르게 말했듯이, 이것은 for each loop같은 오래된 것보다 구문 설탕 for loop이며 컴파일러는 그것을 같은 오래된 for 루프로 변환합니다.

javac (open jdk)에는 -XD-printflat모든 구문 설탕이 제거 된 java 파일을 생성하는 switch가 있습니다. 완전한 명령은 다음과 같습니다

javac -XD-printflat -d src/ MyFile.java

//-d is used to specify the directory for output java file

그래서 구문 설탕을 제거하자

이 질문에 대답하기 위해, 나는 파일을 생성의 두 가지 버전을 쓴 for each, 하나 arrayA를하고 다른 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);
            }
        }
    }
}

각 루프에 대한 다른 구문 설탕 (Autoboxing)과 함께 간단한 루프로 변경되었음을 알 수 있습니다.


-2
List<Item> Items = obj.getItems();
for(Item item:Items)
             {
                System.out.println(item); 
             }

항목 테이블의 모든 오브젝트를 반복합니다.


1
사용자가 구문을 요청하지 않았습니다
pradipgarala
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.