जावा 'प्रत्येक' लूप के लिए कैसे काम करता है?


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 ( : )मुहावरे का उपयोग नहीं कर सकते हैं , क्योंकि वास्तविक पुनरावृत्त केवल अनुमान है।

जैसा कि डेनिस ब्यूनो ने नोट किया था, यह कोड किसी भी ऑब्जेक्ट के लिए काम करता है जो Iterableइंटरफ़ेस को लागू करता है

इसके अलावा, अगर for (:)मुहावरे का दाहिना हाथ arrayकिसी Iterableवस्तु के बजाय होता है , तो आंतरिक कोड एक इंट इंडेक्स काउंटर का उपयोग करता है और array.lengthइसके बजाय जांच करता है । जावा लैंग्वेज स्पेसिफिकेशन देखें ।


14
मैंने पाया है कि कुछ समय के लिए एक लूप कॉल किया गया है जबकि (someList.hasMoreElements ()) {// do something}} - मुझे कोडिंग ग्रेस के करीब पहुंचता है जब मैंने इस प्रश्न की खोज की तो मुझे उम्मीद थी।
जेम्स टी स्नेल

6
इसके अलावा docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html देखें जो फ़ॉरच लूप की व्याख्या करती हैं (जब इसे पेश किया गया था)
फोनिक्स

1
एंड्रॉइड स्टूडियो डेवलपर्स के लिए: import java.util.Iterator;औरimport java.lang.Iterable;
dsdsdsdsd

निराशा की java.util.Iteratorबात है Iterableकि आप इसे लागू नहीं कर सकते for(String s : (Iterator<String>)foo)। मैं समझता हूँ कि ऐसा क्यों है, लेकिन यह है परेशान।
क्रिस्टोफर

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 () का उपयोग करने की आवश्यकता है; अपने पाश में, या किसी तरह से वास्तविक पुनरावृत्ति तक पहुँचने के लिए, आप (:) मुहावरे के लिए उपयोग नहीं कर सकते, क्योंकि वास्तविक Iterator केवल अनुमान है।

[डेनिस ब्यूनो]

यह nsayer के जवाब से निहित है, लेकिन यह ध्यान देने योग्य है कि ओपी के लिए (..) सिंटैक्स तब काम करेगा जब "someList" कुछ भी हो जो java.lang.Iterable को लागू करता है - इसके लिए सूची या कुछ संग्रह नहीं होना चाहिए java.util। यहां तक ​​कि अपने स्वयं के प्रकार, इसलिए, इस सिंटैक्स के साथ उपयोग किया जा सकता है।


161

foreachपाश , में जोड़ा जावा 5 (भी बुलाया "पाश के लिए बढ़ाया"), एक का उपयोग कर के बराबर है java.util.Iteratorएक ही बात के लिए -यह के वाक्यात्मक चीनी। इसलिए, प्रत्येक तत्व को पढ़ते समय, एक-एक करके और क्रम में, एक 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
   }
}

यद्यपि आप मैन्युअल रूप से एक अलग इंडेक्स इंट-चर बना सकते हैं foreach,

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

यह अनुशंसित नहीं है, क्योंकि चर-गुंजाइश आदर्श नहीं है, और मूल forलूप इस उपयोग के मामले के लिए केवल मानक और अपेक्षित प्रारूप है।

foreachबनाम for: प्रदर्शन

जब संग्रह तक पहुँचने, एक foreachहै काफी तेजी बुनियादी से forपाश की सरणी का उपयोग कर सकते। हालांकि, सरणियों तक पहुंचना - कम से कम आदिम और आवरण-सरणियों के साथ - अनुक्रमित के माध्यम से पहुंच नाटकीय रूप से तेज है।

आदिम अंतर-सरणियों के लिए पुनरावृत्ति और सूचकांक पहुंच के बीच अंतर को समयबद्ध करना

पहुँच या सरणियों के दौरान सूचकांक पुनरावृत्तियों की तुलना में 23- 40 प्रतिशत अधिक तेज़ होते हैं। इस पोस्ट के निचले भाग में परीक्षण वर्ग से आउटपुट है, जो 100-तत्व के प्राइमिटिव-इंट एरे (ए इटरेटर, बी इंडेक्स है) में संख्याओं को जमा करता है:intInteger

[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, हालांकि, पुनरावृत्तियाँ स्पष्ट विजेता हैं। बस टेस्ट-क्लास में इंट-ऐरे को इसमें बदलें:

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>, lengthकरने के लिए 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)

एक परीक्षण में वे लगभग बराबर होते हैं, लेकिन संग्रह के साथ, पुनरावृत्त जीतता है।

* यह पोस्ट स्टैक ओवरफ्लो पर लिखे गए दो उत्तरों पर आधारित है:

कुछ और जानकारी: जो अधिक कुशल है, प्रत्येक के लिए एक लूप, या एक इटरेटर?

पूर्ण परीक्षण वर्ग

मैंने इस सवाल को स्टैन ओवरफ़्लो पर पढ़ने के बाद यह तुलना करने वाली समय-समय पर करने वाली किसी भी दो-चीजों की क्लास बनाई :

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
यह उत्तर अब एक ब्लॉग पोस्ट है और दो संबंधित उत्तरों से बनाया गया है जो मैंने लिखा है: यहां और यहां । इसमें दो कार्यों की गति (तल पर) की तुलना के लिए एक सामान्य रूप से उपयोगी वर्ग भी शामिल है।
aliteralmind

1
यहाँ सिर्फ एक छोटी सी टिप्पणी, आपको स्पष्ट रूप से यह नहीं बताना चाहिए कि (:) सिंटैक्स संग्रह को एक्सेस करने के लिए हमेशा बेहतर होता है; यदि आप एक सरणी सूची का उपयोग कर रहे हैं, तो (:) लूप लगभग 2 x धीमा होगा (int i = 0, len = arrayList.size (); i <len; i ++) के लिए उपयोग करने से। मुझे लगता है कि आपने उल्लेख किया है कि [लिंक] में ( stackoverflow.com/questions/2113216/… ) लिंक वैसे भी, लेकिन यह उजागर करना महत्वपूर्ण है कि ...
Leo

@ लिओ यह एक अच्छी बात है। एक ArrayList संग्रह है, लेकिन यह एक सरणी द्वारा समर्थित है, यही वजह है कि इसके लिए सामान्य बेहतर है।
एलिटरालमिंड

मुझे for(int value : int_array) {/* loop content */}लगता है कि यह आपके परीक्षण में सबसे धीमा है क्योंकि यह वाक्यात्मक रूप से समकक्ष है for(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}, जो कि आपके परीक्षण की तुलना नहीं करता है।
8

(वैसे, मैं यह नहीं कह रहा हूं कि आपका परीक्षण अमान्य है, लेकिन यह अंतर के पीछे के कारणों पर ध्यान देने योग्य हो सकता है ताकि लोग यह चुन सकें कि उनके विशेष परिदृश्य के लिए क्या सही है। यदि वे int value = int_array[i];उनके लिए शुरुआत में कर रहे हैं। लूप, फिर वे भी फ़ॉरच का उपयोग कर सकते हैं। जब तक कि उन्हें किसी कारण से सूचकांक तक पहुंच की आवश्यकता न हो। संक्षेप में, यह सब संदर्भ पर निर्भर करता है।)
डस्कोग

129

यहां एक उत्तर दिया गया है जो जावा इटरेटर का ज्ञान ग्रहण नहीं करता है। यह कम सटीक है, लेकिन यह शिक्षा के लिए उपयोगी है।

प्रोग्रामिंग करते समय हम अक्सर ऐसा कोड लिखते हैं जो निम्नलिखित की तरह दिखता है:

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

फ़ॉरेस्ट सिंटैक्स इस सामान्य पैटर्न को अधिक प्राकृतिक और कम वाक्यात्मक रूप से शोर तरीके से लिखने की अनुमति देता है।

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

इसके अतिरिक्त यह सिंटैक्स ऑब्जेक्ट्स जैसे सूचियों या सेटों के लिए मान्य है जो सरणी अनुक्रमण का समर्थन नहीं करते हैं, लेकिन जो जावा Iterable इंटरफ़ेस को लागू करते हैं।


40

जावा में प्रत्येक लूप के लिए अंतर्निहित पुनरावृत्ति तंत्र का उपयोग किया जाता है। तो यह निम्नलिखित के समान है:

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

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

25

जावा 8 सुविधाओं में आप इसका उपयोग कर सकते हैं:

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

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

उत्पादन

First
Second
Third

7
यह यादृच्छिक जानकारी दूर से भी सवाल का जवाब नहीं देती है
टिम

25

यह nsayer के जवाब से निहित है, लेकिन यह ध्यान देने योग्य है कि ओपी के लिए (..) सिंटैक्स तब काम करेगा जब "someList" कुछ भी हो जो java.lang.Iterable को लागू करता है - इसके लिए सूची या कुछ संग्रह नहीं होना चाहिए java.util। यहां तक ​​कि अपने स्वयं के प्रकार, इसलिए, इस सिंटैक्स के साथ उपयोग किया जा सकता है।


1
fd सही है - आंतरिक कोड जब दाएं-हाथ की ओर (:) मुहावरे को एक Iterator लाने के बजाय एक int और array.length का उपयोग करता है। फ़ोरम। sun.com/thread.jspa?messageID=2743233
nsayer

24

जेएलएस में परिभाषित के लिए प्रत्येक लूप के दो रूप हो सकते हैं:

  1. यदि अभिव्यक्ति का प्रकार 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. यदि अभिव्यक्ति जरूरी एक सरणी प्रकार है 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);
    }

जावा 8 ने ऐसी धाराएँ प्रस्तुत की हैं जो आम तौर पर बेहतर प्रदर्शन करती हैं। हम उनका उपयोग इस प्रकार कर सकते हैं:

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

2
सबसे प्रासंगिक और सटीक उत्तर। के लिए मुग्ध वास्तव में दो अनुवाद हैं।
जरायल

23

एक फॉरेस्ट लूप सिंटैक्स है:

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

चेतावनी: आप फॉरेस्ट लूप के साथ एरे तत्वों को एक्सेस कर सकते हैं, लेकिन आप उन्हें इनिशियलाइज़ नहीं कर सकते। उसके लिए मूल 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";
}

अब अगर हम कंसोल को डंप करते हैं, तो हमें यह मिलता है:

hello
2 is cool
hello
hello

21

जावा "प्रत्येक के लिए" लूप निर्माण दो प्रकार की वस्तुओं पर पुनरावृत्ति की अनुमति देगा:

  • T[] (किसी भी प्रकार के सरणियाँ)
  • java.lang.Iterable<T>

Iterable<T>इंटरफेस केवल एक विधि है: Iterator<T> iterator()। यह प्रकार की वस्तुओं पर काम करता है Collection<T>क्योंकि Collection<T>इंटरफ़ेस का विस्तार होता है Iterable<T>


16

विकिपीडिया में उल्लिखित एक फॉरेस्ट लूप की अवधारणा नीचे दी गई है:

लूप निर्माण के लिए अन्य के विपरीत, हालांकि, फ़ॉरच लूप आमतौर पर कोई स्पष्ट काउंटर नहीं रखते हैं : वे अनिवार्य रूप से कहते हैं "इस सेट में सब कुछ करें", बजाय "यह एक्स बार करें"। यह संभावित ऑफ-बाय-वन त्रुटियों से बचा जाता है और कोड को पढ़ने में सरल बनाता है।

तो एक फॉर्च्यूप लूप की अवधारणा बताती है कि लूप किसी भी स्पष्ट काउंटर का उपयोग नहीं करता है, जिसका अर्थ है कि सूची में अनुक्रमण के लिए अनुक्रमित का उपयोग करने की कोई आवश्यकता नहीं है, इसलिए यह उपयोगकर्ता को एक-एक त्रुटि से बचाता है। इस ऑफ-बाय-वन त्रुटि की सामान्य अवधारणा का वर्णन करने के लिए, आइए अनुक्रमणिका का उपयोग करते हुए एक सूची में पार करने के लिए एक लूप का उदाहरण लें।

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

}

लेकिन मान लें कि यदि सूची 1 इंडेक्स से शुरू होती है तो यह लूप एक अपवाद को फेंकने वाला है क्योंकि इसमें इंडेक्स 0 पर कोई तत्व नहीं पाया जाएगा और इस त्रुटि को ऑफ-बाय-वन एरर कहा जाता है। तो इस ऑफ-बाय-वन एरर से बचने के लिए, फॉर्च लूप की अवधारणा का उपयोग किया जाता है। अन्य फायदे भी हो सकते हैं, लेकिन मुझे लगता है कि यह मुख्य अवधारणा और फॉरच लूप के उपयोग का लाभ है।


13

जावा 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);
});


11

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

अधिक जानकारी के लिए इस लिंक को देखें।

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


10

यहाँ एक समकक्ष अभिव्यक्ति है।

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

10

यह भी ध्यान दें कि मूल प्रश्न में "फॉर्च्यूनर" विधि का उपयोग करने की कुछ सीमाएं हैं, जैसे कि पुनरावृत्ति के दौरान सूची से आइटम को निकालने में सक्षम नहीं होना।

नया फॉर-लूप पढ़ने में आसान है और एक अलग इटरेटर की आवश्यकता को हटा देता है, लेकिन केवल-पढ़ने के लिए वातन पास में वास्तव में प्रयोग करने योग्य है।


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
उल्लेख किया जाना चाहिए कि यह जावा 1.8 में जोड़ा गया है
TheLibrarian

हम यह सुनिश्चित नहीं कर सकते हैं कि एक ही धागे का उपयोग किया जाए। for(अगर मुझे यह सुनिश्चित करने के लिए कि मुझे उसी धागे का उपयोग करना है, तो मुझे फॉर्म का उपयोग करना पसंद है। अगर मुझे मल्टीथ्रेडेड निष्पादन की अनुमति देना पसंद है तो मुझे स्ट्रीम-फॉर्म का उपयोग करना पसंद है।
ग्रिम

8

यह सभी बुनियादी लूपिंग अव्यवस्था को हटाकर आपके कोड में सुंदरता जोड़ता है। यह नीचे दिए गए आपके कोड को एक साफ रूप देता है।

सामान्य forलूप:

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

प्रत्येक के लिए उपयोग करना:

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

for- प्रत्येक एक संग्रह पर एक निर्माण है जो Iterator को लागू करता है । याद रखें कि, आपके संग्रह को Iterator लागू करना चाहिए ; अन्यथा आप प्रत्येक के लिए इसका उपयोग नहीं कर सकते।

निम्नलिखित लाइन "के रूप में पढ़ा जाता है सूची में प्रत्येक TimerTask टी के लिए। "

for (TimerTask t : list)

प्रत्येक के मामले में त्रुटियों की संभावना कम है। आपको पुनरावृत्ति शुरू करने या लूप काउंटर को शुरू करने और इसे समाप्त करने (जहां त्रुटियों की गुंजाइश है) के बारे में चिंता करने की ज़रूरत नहीं है।


8

जावा 8 से पहले, आपको निम्नलिखित का उपयोग करने की आवश्यकता है:

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

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

हालाँकि, जावा 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
एलेक्स78191

7

यह कुछ इस तरह दिखेगा। बहुत गँवार।

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

सन डॉक्यूमेंटेशन में प्रत्येक के लिए एक अच्छा राइटअप है ।


6

जैसा कि कई अच्छे जवाबों में कहा गया है, एक वस्तु को लागू करना चाहिए 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लूप का उपयोग करने की कोशिश करता है तो फेंक देगा ।


6

प्रत्येक पाश के लिए जावा (उर्फ पाश के लिए बढ़ाया) पाश के लिए एक का एक सरलीकृत संस्करण है। फायदा यह है कि लिखने के लिए कम कोड है और प्रबंधन करने के लिए कम चर। नकारात्मक पक्ष यह है कि आपके पास चरण मान पर कोई नियंत्रण नहीं है और लूप बॉडी के अंदर लूप इंडेक्स तक कोई पहुंच नहीं है।

जब चरण मान 1 का एक साधारण वेतन वृद्धि हो और जब आपको केवल वर्तमान लूप तत्व तक पहुंच की आवश्यकता हो तो उनका सबसे अच्छा उपयोग किया जाता है। उदाहरण के लिए, यदि आपको किसी तत्व या संग्रह में हर तत्व को मौजूदा तत्व के आगे या पीछे झांकने के बिना लूप करने की आवश्यकता है।

लूप इनिशियलाइज़ेशन नहीं है, बूलियन कंडीशन नहीं है और स्टेप वैल्यू निहित है और एक साधारण वेतन वृद्धि है। यही कारण है कि उन्हें छोरों के लिए नियमित रूप से बहुत सरल माना जाता है।

फंदे के लिए बढ़ाया निष्पादन के इस आदेश का पालन करें:

1) पाश शरीर

2) चरण 1 से दोहराएँ जब तक पूरे सरणी या संग्रह का पता लगाया गया है

उदाहरण - इंटेगर एरे

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

CurrentValue वैरिएबल वर्तमान मान को intArray एरे में लूप किया जा रहा है। ध्यान दें कि कोई स्पष्ट स्टेप वैल्यू नहीं है - यह हमेशा 1 से बढ़ा हुआ है।

बृहदान्त्र का मतलब "इन" माना जा सकता है। तो लूप डिक्लेरेशन स्टेट्स के लिए एन्हांस किया गया: इंट्रैरे पर लूप और करेंटव्यू वेरिएबल में करंट ऐरे इंट वैल्यू को स्टोर करें।

आउटपुट:

1
3
5
7
9

उदाहरण - स्ट्रिंग ऐरे

हम स्ट्रिंग के एक सरणी पर पुनरावृति करने के लिए प्रत्येक लूप का उपयोग कर सकते हैं। लूप डिक्लेरेशन में कहा गया है: मायस्टार्स स्ट्रिंग ऐरे पर लूप और करंट स्ट्रिंग वेरिएबल में करंट स्ट्रिंग वैल्यू स्टोर करें ।

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

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

आउटपुट:

alpha
beta
gamma
delta

उदाहरण - सूची

लूप के लिए संवर्धित का उपयोग java.util पर करने के लिए किया जा सकता है। इस प्रकार है:

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

लूप डिक्लेरेशन बताता है: लूप ऑफ़ मायस्ट लिस्ट ऑफ़ स्ट्रिंग्स और करंट लिस्ट वैल्यू को करेंटइम वेरिएबल में स्टोर करते हैं ।

आउटपुट:

alpha
beta
gamma
delta

उदाहरण - सेट

लूप के लिए संवर्धित का उपयोग java.util पर सेट करने के लिए भी किया जा सकता है। इस प्रकार है:

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

स्रोत: जावा में लूप - अंतिम गाइड



3

जावा के लिए प्रत्येक मुहावरे को केवल * Iterable के सरणियों या वस्तुओं पर लागू किया जा सकता है । यह मुहावरा अंतर्निहित है क्योंकि यह वास्तव में एक Iterator द्वारा समर्थित है। Iterator प्रोग्रामर द्वारा क्रमादेशित है और अक्सर अपनी स्थिति पर नज़र रखने के लिए एक पूर्णांक सूचकांक या एक नोड (डेटा संरचना के आधार पर) का उपयोग करता है। कागज पर यह एक नियमित रूप से लूप की तुलना में धीमा है, कम से कम "रैखिक" संरचनाओं जैसे सरणियों और सूचियों के लिए लेकिन यह अधिक से अधिक अमूर्तता प्रदान करता है।


-1: यह तरीका कम पठनीय है (आम तौर पर): यहां तक ​​कि आपका अपना उदाहरण (पहला वाला) गलत है, क्योंकि यह सरणी में पहला तत्व छोड़ता है।
ओन्ड्रेज स्कोपेक

2

यह पागल लग रहा है लेकिन अरे यह काम करता है

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

यह काम। जादू


1
इसके लिए जावा 1.8 +
BARNI

2
दूर से भी इस सवाल का जवाब नहीं देता
टिम

2

अन्य उत्तरों में से कई सही रूप में for each loopबताए गए हैं, वही पुराने की तुलना में सिंटैक्टिक चीनी है for loopऔर कंपाइलर लूप के लिए उसी पुराने में अनुवाद करता है।

javac (ओपन jdk) में एक स्विच होता है -XD-printflat, जो एक जावा फाइल बनाता है, जिसमें सभी सिन्नेटिक शुगर को हटा दिया जाता है। पूरा कमांड इस तरह दिखता है

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

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

तो चलिए वाक्य रचना चीनी को हटा दें

इस सवाल का जवाब देने के लिए, मैंने एक फाइल बनाई और दो संस्करण लिखे for each, एक के साथ 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);
            }
        }
    }
}

आप देख सकते हैं कि प्रत्येक छोरों के लिए अन्य वाक्यविन्यास चीनी (ऑटोबॉक्सिंग) के साथ सरल छोरों में परिवर्तित हो गए।


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

आइटम तालिका में सभी ऑब्जेक्ट्स पर Iterates।


1
उपयोगकर्ता ने वाक्य रचना के लिए नहीं पूछा है
pradipgarala
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.