Her bir 'döngü için' Java nasıl çalışır?


1498

Düşünmek:

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

Her sözdizimi foriçin for kullanılmadan eşdeğer döngü nasıl görünürdü?


Yanıtlar:


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

Döngünüzde kullanmanız i.remove();veya gerçek yineleyiciye bir şekilde erişmeniz gerekiyorsa, gerçek yineleyicinin for ( : )yalnızca çıkartıldığı için deyimi kullanamayacağınızı unutmayın .

Denis Bueno tarafından belirtildiği gibi, bu kod Iterablearabirimi uygulayan herhangi bir nesne için çalışır .

Ayrıca, for (:)deyimin sağ tarafı arraybir Iterablenesneden ziyade , dahili kod bir int dizin sayacı kullanır ve array.lengthbunun yerine denetler . Java Dil Belirtimi'ne bakın .


14
Ben sadece bir while döngüsü çağırma buldum gibi süre (someList.hasMoreElements ()) {// bir şey yapmak}} - bu soruyu aradığımda bulmayı umduğum kodlama zarafet yakın alır.
James T Snell

6
Ayrıca , foreach döngüsünü açıklayan docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html adresine bakın (tanıtıldığında)
PhoneixS

1
android stüdyo geliştiricileri için: import java.util.Iterator;veimport java.lang.Iterable;
dsdsdsdsd

Sinir bozucu java.util.Iteratordeğil , bu Iterableyüzden yapamaz for(String s : (Iterator<String>)foo). Bunun olduğunu anlamak, ancak edilir rahatsız edici.
Christopher Schultz

499

Yapı her biri için de diziler için geçerlidir. Örneğin

String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };

for (String fruit : fruits) {
    // fruit is an element of the `fruits` array.
}

ki bu aslında

for (int i = 0; i < fruits.length; i++) {
    String fruit = fruits[i];
    // fruit is an element of the `fruits` array.
}

Yani, özet:
[nsayer] Aşağıdakiler olanların daha uzun biçimidir:

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

İ.remove () kullanmanız gerekirse; gerçek yineleyici yalnızca çıkartıldığı için for (:) deyimini kullanamazsınız.

[Denis Bueno]

Nsayer cevabı tarafından ima edilir, ancak "someList" java.lang.Iterable uygulayan herhangi bir şey olduğunda (..) sözdizimi için OP'lerin çalışacağını belirtmek gerekir. java.util. Bu nedenle, kendi türleriniz bile bu sözdizimi ile kullanılabilir.


161

foreachDöngü eklenen, Java 5 , (aynı zamanda "döngü gelişmiş" olarak adlandırılır) kullanarak eşdeğerdir java.util.Iteratoraynı şey için --O en sözdizimsel şeker. Bu nedenle, her bir öğeyi tek tek ve sırayla okurken foreach, daha rahat ve özlü olduğu için her zaman bir yineleyici üzerinden seçilmelidir.

her biri için

for(int i : intList) {
   System.out.println("An element in the list: " + i);
}

yineleyici

Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
   System.out.println("An element in the list: " + intItr.next());
}

IteratorDoğrudan kullanmanız gereken durumlar vardır . Örneğin, bir foreachcan (will?) Kullanırken bir öğeyi silmeye çalışmak a ConcurrentModificationException.

foreachvs for.: Temel farklılıklar

Arasındaki tek pratik fark forve foreachdizine eklenebilir nesnelerin durumda, dizine erişimi olmayan, yani. Temel fordöngü gerektiğinde bir örnek :

for(int i = 0; i < array.length; i++) {
   if(i < 5) {
      // Do something special
   }  else {
      // Do other stuff
   }
}

Manuel olarak ayrı bir dizin int değişkeni oluşturabilseniz de foreach,

int idx = -1;
for(int i : intArray) {
   idx++;
   ...
}

değişken kapsam ideal olmadığından tavsiye edilmez ve temel fordöngü bu kullanım durumu için standart ve beklenen biçimdir.

foreachvs for.: Performans

Koleksiyonlara erişirken a foreach, temel döngünün dizi erişiminden önemli ölçüde daha hızlıdırfor . Bununla birlikte, dizilere erişirken - en azından ilkel ve sargı dizileriyle - dizinler yoluyla erişim önemli ölçüde daha hızlıdır.

İlkel int diziler için yineleyici ve dizin erişimi arasındaki farkın zamanlaması

Endeksler 23- vardır 40 erişirken Yineleyicilerin verdiğinden yüzde hızlı intveya Integerdiziler. 100 öğeli bir ilkel-int dizisindeki sayıları toplayan bu yazının altındaki test sınıfından çıktı (A yineleyici, B indekstir):

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

Bunu bir Integerdizi için de çalıştırdım ve dizinler hala açık kazanıyor, ancak sadece yüzde 18 ila 25 daha hızlı.

Koleksiyonlar için yineleyiciler dizinlerden daha hızlıdır

Bir İçin Listbölgesinin IntegersAncak yineleyiciler açık kazanan vardır. Test sınıfındaki int dizisini şu şekilde değiştirin:

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

Ve test fonksiyonunda ( int[]to List<Integer>, lengthto size(), vb.) Gerekli değişiklikleri yapın :

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

Bir testte neredeyse eşdeğerdirler, ancak koleksiyonlarda yineleyici kazanır.

* Bu yazı Stack Overflow üzerine yazdığım iki cevaba dayanıyor:

Daha fazla bilgi: Hangisi daha verimli, her döngü için mi, yineleyici mi?

Tam test sınıfı

Stack Overflow üzerinde bu soruyu okuduktan sonra herhangi bir-iki-şeyler-yapmak-zaman-için-bu-karşılaştırma-sınıf oluşturduk :

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
Bu cevap artık bir blog yazısı ve yazdığım ilgili iki cevaptan oluşturuldu: burada ve burada . Ayrıca, iki fonksiyonun (altta) hızını karşılaştırmak için genel olarak kullanışlı bir sınıf içerir.
aliteralmind

1
Burada sadece bir küçük yorum, kategorik olarak (:) sözdiziminin koleksiyonlara erişmek için her zaman daha iyi olduğunu belirtmemelisiniz; bir dizi listesi kullanıyorsanız, for (:) döngüsü for (int i = 0, len = arrayList.size (); i <len; i ++) 'a göre yaklaşık 2 kat daha yavaş olacaktır. Sanırım [link] ( stackoverflow.com/questions/2113216/… ) bağlantısında yine de bahsettiğinizi , ancak bunu vurgulamak önemlidir ...
Leo

@Leo İyi bir nokta. Bir ArrayList Koleksiyon'dur, ancak bir dizi tarafından desteklenir, bu yüzden bunun için normal daha iyidir.
aliteralmind

for(int value : int_array) {/* loop content */}Testinizde en yavaş olduğunu tahmin ediyorum , çünkü sözdizimsel olarak eşdeğerdir for(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}, bu testinizin karşılaştırdığı şey değildir.
daiscog

(bu arada, ben test geçersiz demiyorum, ama insanlar kendi özel senaryo için doğru olanı seçmek, böylece farkı ardındaki nedenleri kayda değer olabilir. Onlar yapıyorsanız int value = int_array[i];aksiyonları için başında döngü, o zaman foreach de kullanabilirler.
Dizine erişmeleri gerekmedikçe

129

İşte Java Yineleyiciler hakkında bilgi sahibi olmayan bir cevap. Daha az kesindir, ancak eğitim için yararlıdır.

Programlama sırasında genellikle aşağıdaki gibi görünen bir kod yazarız:

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]
}

Öngörüm sözdizimi, bu ortak örüntünün daha doğal ve daha az sözdizimsel olarak daha gürültülü bir şekilde yazılmasına izin verir.

for(char grade : grades) {   // foreach grade in grades
    System.out.print(grade); // print that grade
}

Ayrıca, bu sözdizimi Listeler veya Kümeler gibi dizi indekslemeyi desteklemeyen ancak Java Yinelenebilir arabirimini uygulayan nesneler için de geçerlidir.


40

Java'daki for-each döngüsü temel yineleyici mekanizmasını kullanır. Yani aşağıdakilerle aynı:

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

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

25

Java 8 özelliklerinde şunları kullanabilirsiniz:

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

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

Çıktı

First
Second
Third

7
bu rastgele bilgi bile soruyu uzaktan cevaplamıyor
Tim

25

Nsayer cevabı tarafından ima edilir, ancak "someList" java.lang.Iterable uygulayan herhangi bir şey olduğunda (..) sözdizimi için OP'lerin çalışacağını belirtmek gerekir. java.util. Bu nedenle, kendi türleriniz bile bu sözdizimi ile kullanılabilir.


1
fd doğru - for (:) deyiminin sağ tarafı bir Yineleyici almak yerine int ve array.length kullandığında dahili koddur. forums.sun.com/thread.jspa?messageID=2743233
nsayer

24

Her döngü için JLS'de tanımlandığı gibi iki form olabilir:

  1. İfade türü bir alt türse, Iterableçeviri şu şekildedir:

    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. İfadenin zorunlu olarak bir dizi türü T[]varsa:

    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 genel olarak daha iyi performans gösteren akışları tanıttı. Bunları şu şekilde kullanabiliriz:

someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);

2
En alakalı ve doğru cevap. Enchansed for'un iki çevirisi var.
Zarial

23

Bir foreach döngüsü sözdizimi:

for (type obj:array) {...}

Misal:

String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
    System.out.println(str);
}

Çıktı:

Java
Coffe
Is
Cool

UYARI: Dizi öğelerine foreach döngüsü ile erişebilirsiniz, ancak bunları BAŞLATAMAZSINIZ. Bunun için orijinal fordöngüyü kullanın .

UYARI: Dizinin türünü diğer nesneyle eşleştirmeniz gerekir.

for (double b:s) // Invalid-double is not String

Öğeleri düzenlemek istiyorsanız, orijinal fordöngüyü şu şekilde kullanın:

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

Şimdi konsola atarsak, şunu elde ederiz:

hello
2 is cool
hello
hello

21

Java "for-each" döngü yapısı iki nesne türü üzerinde yinelemeye izin verir:

  • T[] (herhangi bir tür diziler)
  • java.lang.Iterable<T>

Iterable<T>Arayüzü yalnızca bir yöntemi var Iterator<T> iterator(). Arabirim genişletildiği Collection<T>için bu tür nesneler üzerinde çalışır .Collection<T>Iterable<T>


16

Wikipedia'da belirtildiği gibi bir foreach döngüsü kavramı aşağıda vurgulanmıştır:

Bununla birlikte, döngü yapıları için diğerlerinden farklı olarak, foreach döngüleri genellikle açık bir sayaç tutmazlar : "bunu bu x kez yapmak" yerine, "bunu bu kümedeki her şeye yap" derler. Bu, olası tek tek hataları önler ve kodun okunmasını kolaylaştırır.

Bu nedenle, bir foreach döngüsü kavramı, döngünün açık bir sayaç kullanmadığını açıklar; bu, listede geçiş yapmak için dizinlerin kullanılmasına gerek olmadığı anlamına gelir ve böylece kullanıcıyı tek tek hatalardan kurtarır. Bu tek tek hatanın genel kavramını tanımlamak için, dizinleri kullanarak bir listede geçiş yapmak için bir döngü örneği alalım.

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

}

Ancak, listenin dizin 1 ile başlaması durumunda, bu döngü, dizin 0'da hiçbir öğe bulamayacağı ve bu hataya tek tek hata olarak adlandırılacağı için bir istisna atacağını varsayalım. Dolayısıyla bu tek tek hatadan kaçınmak için bir foreach döngüsü kullanılır. Başka avantajlar da olabilir, ancak bir foreach döngüsü kullanmanın ana konsepti ve avantajı olduğunu düşünüyorum.


13

Java 8'de forach'u tanıttılar. Listeyi kullanarak Haritalar döngüye girebilir.

Her biri için bir Liste döngü

List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");

someList.forEach(listItem -> System.out.println(listItem))

veya

someList.forEach(listItem-> {
     System.out.println(listItem); 
});

Her birini kullanarak bir Haritaya Dön

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

veya

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 7Siz de dahil olmak üzere eski Java sürümlerini kullanmak foreachdöngüyü aşağıdaki gibi kullanabilirsiniz .

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

foreachDöngüyü kullanmanın en son yolu aşağıdadırJava 8

(Listeyi forEach+ lambda ifadesi veya yöntem başvurusu ile döngü )

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

Daha fazla bilgi için bu bağlantıya bakın.

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


10

İşte eşdeğer bir ifade.

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

10

Ayrıca, orijinal sorudaki "foreach" yöntemini kullanmanın, yineleme sırasında öğeleri listeden çıkaramama gibi bazı sınırlamalara sahip olduğunu unutmayın.

Yeni for-loop'un okunması daha kolaydır ve ayrı bir yineleyici ihtiyacını ortadan kaldırır, ancak yalnızca salt okunur yineleme geçişlerinde gerçekten kullanılabilir.


1
Bu durumlarda, kullanımı removeIfdoğru araç olabilir
ncmathsadist

9

"Her biri için" kullanımınızdan kaçınmak için forEach'a bir alternatif:

List<String> someList = new ArrayList<String>();

Varyant 1 (düz):

someList.stream().forEach(listItem -> {
    System.out.println(listItem);
});

Varyant 2 (paralel yürütme (daha hızlı)):

someList.parallelStream().forEach(listItem -> {
    System.out.println(listItem);
});

2
Java 1.8'de eklendiğinden bahsetmeliydim
TheLibrarian

Aynı iş parçacığının kullanıldığından% 100 emin olamayız. for(Aynı iş parçacığının kullanıldığından emin olmak için formu kullanmak istiyorum. Çok iş parçacıklı yürütmeye izin vermek istiyorsam akış formunu kullanmayı seviyorum.
Grim

8

Tüm temel döngü karmaşasını kaldırarak kodunuza güzellik katar. Aşağıda haklı olarak kodunuza temiz bir görünüm verir.

Normal fordöngü:

void cancelAll(Collection<TimerTask> list) {
    for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
         i.next().cancel();
}

Her biri için kullanma:

void cancelAll(Collection<TimerTask> list) {
    for (TimerTask t : list)
        t.cancel();
}

for-each , Yineleyici uygulayan bir koleksiyon üzerinde bir yapıdır . Unutmayın, koleksiyonunuz Yineleyici uygulamalıdır ; aksi halde her biri için kullanamazsınız.

Aşağıdaki çizgi "olarak okunur listedeki her TimerTask t için. "

for (TimerTask t : list)

Her biri için hata olasılığı daha azdır. Yineleyiciyi başlatma veya döngü sayacını başlatma ve sonlandırma konusunda endişelenmenize gerek yoktur (hataların kapsamı vardır).


8

Java 8'den önce aşağıdakileri kullanmanız gerekir:

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

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

Ancak, Java 8'de Akışların tanıtılmasıyla aynı şeyi daha az sözdiziminde yapabilirsiniz. Örneğin, someListşunları yapabilirsiniz:

someList.stream().forEach(System.out::println);

Akımlar hakkında daha fazla bilgiyi burada bulabilirsiniz .


The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
Alex78191

7

Böyle bir şey olurdu. Çok acımasız.

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

Üzerinde iyi bir writeup Orada her biri için de Güneş belgelerine .


6

Pek çok iyi yanıtın dediği gibi, bir nesne Iterable interfacebir for-eachdöngü kullanmak istiyorsa uygulamalıdır .

Basit bir örnek göndereceğim ve bir for-eachdöngünün nasıl çalıştığını farklı bir şekilde açıklamaya çalışacağım.

for-eachDöngü, örneğin:

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

Daha sonra, javapbu sınıfı koda dönüştürmek için kullanırsak , bu bayt kodu örneğini alırız:

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;

Örneklemin son satırından da görebileceğimiz gibi, derleyici for-eachanahtar kelime kullanımını Iteratorderleme zamanında otomatik olarak kullanımına dönüştürecektir . Bu, uygulanmayan nesnenin döngüyü kullanmaya çalıştığında neden Iterable interfacebir Exceptionzaman atacağını açıklayabilir for-each.


6

Her döngü için Java (aka döngü gelişmiş) döngü için basitleştirilmiş bir sürümüdür. Avantajı, daha az kod yazılması ve yönetilmesi için daha az değişken olmasıdır. Dezavantajı, adım değeri üzerinde hiçbir denetiminiz olmaması ve döngü gövdesi içindeki döngü dizinine erişiminizin olmamasıdır.

Adım değeri 1 değerinde basit bir artış olduğunda ve yalnızca geçerli döngü öğesine erişmeniz gerektiğinde en iyi şekilde kullanılırlar. Örneğin, geçerli öğenin önüne veya arkasına bakmadan bir dizideki veya Koleksiyondaki her öğenin üzerinde döngü yapmanız gerekiyorsa.

Döngü başlatma yok, boolean koşulu yok ve adım değeri örtük ve basit bir artış. Bu yüzden döngüler için normalden çok daha basit olarak kabul edilirler.

Döngüler için geliştirilmiş bu yürütme sırasını izleyin:

1) döngü gövdesi

2) dizi veya koleksiyonun tamamı geçilinceye kadar 1. adımdan itibaren tekrarlayın

Örnek - Tamsayı Dizisi

int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
  System.out.println(currentValue);
}

CurrentValue değişkeni, intArray dizisinde döngülenmekte olan geçerli değeri tutar. Açık bir adım değeri olmadığına dikkat edin - bu her zaman 1 artar.

İki nokta üst üste “in” anlamına gelebilir. Yani döngü beyanı devletler için geliştirilmiş: intArray üzerinde döngü ve cari dizi int değerini depolamak içinde CurrentValue değişken.

Çıktı:

1
3
5
7
9

Örnek - Dize Dizisi

Bir dizge dizisini yinelemek için for-each döngüsünü kullanabiliriz. Döngü bildirimi durumları: myStrings dize dizisine üzerinde döngü ve mevcut String değeri saklamak içinde currentString değişken.

String [] myStrings  = {
  "alpha",
  "beta",
  "gamma",
  "delta"
};

for(String currentString : myStrings) {
  System.out.println(currentString);
}

Çıktı:

alpha
beta
gamma
delta

Örnek - Liste

Geliştirilmiş döngü, bir java.util.List üzerinden aşağıdaki gibi yineleme yapmak için de kullanılabilir:

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

Döngü beyanı devletler: Strings myList Listesi üzerinde döngü ve cari Liste değerini depolamak içinde currentltem değişkeni.

Çıktı:

alpha
beta
gamma
delta

Örnek - Ayarla

Geliştirilmiş döngü, bir java.util.Set üzerinde aşağıdaki gibi yineleme yapmak için de kullanılabilir:

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

Döngü beyanı devletler: Strings mySet Set üzerinde döngü ve cari Set değerini depolamak içinde currentltem değişkeni. Bu bir Set olduğundan, yinelenen Dize değerlerinin saklanmadığına dikkat edin.

Çıktı:

alpha
delta
beta
gamma

Kaynak: Java'daki Döngüler - 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

Her bir deyim için Java yalnızca * Yinelenebilir tipindeki dizilere veya nesnelere uygulanabilir . Bu deyim olan örtülü gerçekten bir Yineleyiciyi tarafından desteklenen olarak. Yineleyici programcı tarafından programlanır ve konumunu izlemek için genellikle bir tamsayı dizini veya bir düğüm (veri yapısına bağlı olarak) kullanır. Kağıt üzerinde normal bir döngüden daha yavaştır, en azından diziler ve Listeler gibi "doğrusal" yapılar için ama daha büyük soyutlama sağlar.


-1: bu daha az okunabilir (genellikle): dizideki ilk öğeyi bıraktığı için kendi örneğiniz (ilk örnek) bile yanlıştır.
Ondrej Skopek

2

Bu çılgınca görünüyor ama hey işe yarıyor

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

Bu çalışıyor. sihirli


1
Bu, Java 1.8 +
BARNI

2
soruyu uzaktan bile cevaplamıyor
Tim

2

Diğer cevapların birçoğu doğru şekilde belirtildiği gibi for each loop, aynı eski üzerinde sadece sözdizimsel şekerdir for loopve derleyici bunu döngü için aynı eskiye çevirir.

javac (open jdk), -XD-printflatsözdizimsel şekerin kaldırıldığı bir java dosyası oluşturan bir anahtara sahiptir . tam komut şuna benzer

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

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

Yani sözdizimsel şekeri kaldıralım

Bu soruyu cevaplamak için bir dosya oluşturdum ve for eachbiri ile arraydiğeri de ile iki sürümü yazdım list. Benim javadosyası bu benziyordu.

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

Ben compiledyukarıdaki anahtarı ile bu dosya, ben aşağıdaki çıktı aldım.

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

Her bir döngü için diğer sözdizimsel şekerin (Otomatik Boks) birlikte basit döngülere dönüştüğünü görebilirsiniz.


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

Öğeler tablosundaki tüm nesneler üzerinde yineleme yapar.


1
Kullanıcı sözdizimi istemedi
pradipgarala
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.