سؤال

يعتبر:

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

ما من شأنه أن يعادل for تبدو الحلقة بدون استخدام لكل بناء الجملة؟

هل كانت مفيدة؟

المحلول

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

لاحظ أنه إذا كنت بحاجة إلى استخدام i.remove(); في حلقتك، أو الوصول إلى المكرر الفعلي بطريقة ما، لا يمكنك استخدام for ( : ) المصطلح، حيث يتم استنتاج المكرر الفعلي فقط.

كما لاحظ دينيس بوينو، فإن هذا الرمز يعمل مع أي كائن يقوم بتنفيذ Iterable واجهه المستخدم.

وكذلك إذا كان الجانب الأيمن من for (:) المصطلح هو array بدلا من Iterable الكائن، يستخدم الكود الداخلي عداد فهرس int ويقوم بالتحقق منه array.length بدلاً من.انظر مواصفات لغة جافا.

نصائح أخرى

البناء لكل صالح أيضًا للمصفوفات.على سبيل المثال

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

إذن الملخص العام:
[نصير] ما يلي هو الشكل الأطول لما يحدث:

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

لاحظ أنه إذا كنت بحاجة إلى استخدام i.remove () ؛في حلقتك ، أو الوصول إلى التكرار الفعلي بطريقة ما ، لا يمكنك استخدام (:) المصطلح ، لأن التكرار الفعلي يتم استنتاجه فقط.

[دينيس بوينو]

إنه ضمنيًا من خلال إجابة Nsayer ، لكن تجدر الإشارة إلى أن بناء الجملة (..) سيعمل عندما يكون "Somelist" أي شيء ينفذ java.lang.iterable - لا يجب أن يكون قائمة أو مجموعة من المجموعات java.util.حتى الأنواع الخاصة بك ، لذلك ، يمكن استخدامها مع هذا بناء الجملة.

ال foreach حلقة, ، أضيفت في جافا 5 (وتسمى أيضًا "حلقة for المحسّنة")، أي ما يعادل استخدام ملف java.util.Iterator- إنه السكر النحوي لنفس الشيء.ولذلك، عند قراءة كل عنصر، واحدا تلو الآخر، وبالترتيب، أ foreach يجب دائمًا اختياره بدلاً من المكرر، لأنه أكثر ملاءمة وإيجازًا.

com.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 Loop هو ببساطة التنسيق القياسي والمتوقع لحالة الاستخدام هذه.

foreach ضد. for:أداء

عند الوصول إلى المجموعات، أ foreach يكون أسرع بكثير من الأساسية for الوصول إلى صفيف الحلقة.ومع ذلك، عند الوصول إلى المصفوفات - على الأقل مع المصفوفات البدائية والمصفوفات المجمعة - يكون الوصول عبر الفهارس أسرع بشكل كبير.

توقيت الفرق بين الوصول إلى المكرر والفهرس للصفائف int البدائية

الفهارس هي 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, ومع ذلك، فإن التكرارات هي الفائز الواضح.ما عليك سوى تغيير الصفيف int في فئة الاختبار إلى:

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)

في أحد الاختبارات، يكونان متكافئين تقريبًا، ولكن مع المجموعات، يفوز المُكرِّر.

* يستند هذا المنشور إلى إجابتين كتبتهما على 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;https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java&quot;&gt;https://stackoverflow.com/questions/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

}

إليك إجابة لا تفترض معرفة 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.

تستخدم حلقة for-each في Java آلية التكرار الأساسية.لذلك فهو مطابق لما يلي:

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

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

في ميزات Java 8، يمكنك استخدام هذا:

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

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

انتاج |

First
Second
Third

يتم تضمينه في إجابة nsayer، ولكن تجدر الإشارة إلى أن بناء جملة OP for(..) سيعمل عندما يكون "someList" أي شئ الذي يطبق java.lang.Iterable -- ليس من الضروري أن يكون قائمة، أو مجموعة من java.util.وبالتالي، حتى الأنواع الخاصة بك يمكن استخدامها مع بناء الجملة هذا.

بناء جملة حلقة 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

كما هو محدد في JLS لكل حلقة يمكن أن يكون لها شكلين:

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

قدمت Java 8 تدفقات ذات أداء أفضل بشكل عام.يمكننا استخدامها على النحو التالي:

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

سيسمح بناء حلقة Java "for-each" بالتكرار على نوعين من الكائنات:

  • T[] (مصفوفات من أي نوع)
  • java.lang.Iterable<T>

ال Iterable<T> الواجهة لها طريقة واحدة فقط: Iterator<T> iterator().هذا يعمل على كائنات من النوع Collection<T> بسبب ال Collection<T> تمتد الواجهة Iterable<T>.

تم توضيح مفهوم حلقة foreach كما هو مذكور في ويكيبيديا أدناه:

على عكس غيرها بالنسبة للبناءات الحلقية ، عادة ما تحافظ حلقات 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.

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

وهنا تعبير يعادل.

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

لاحظ أيضًا أن استخدام طريقة "foreach" في السؤال الأصلي له بعض القيود، مثل عدم القدرة على إزالة العناصر من القائمة أثناء التكرار.

تعد حلقة for الجديدة أسهل في القراءة وتزيل الحاجة إلى مكرر منفصل، ولكنها قابلة للاستخدام فقط في تمريرات التكرار للقراءة فقط.

استخدام إصدارات 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);

لمزيد من المعلومات راجع هذا الرابط.

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

بديل لـ 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 حلقة:

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-each.

تتم قراءة السطر التالي كـ "لكل TimerTask t في القائمة."

for (TimerTask t : list)

هناك فرصة أقل لحدوث الأخطاء في حالة لكل منها.لا داعي للقلق بشأن تهيئة المكرِّر أو تهيئة عداد الحلقة وإنهائه (حيث يوجد مجال للأخطاء).

في Java 8، قدموا forEach.باستخدام القائمة، يمكن تكرار الخرائط.

قم بتكرار القائمة باستخدام كل منها

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

سيبدو شيء هكذا.ماكر جدا.

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

هناك كتابة جيدة على لكل في ال توثيق الشمس.

قبل Java 8، تحتاج إلى استخدام ما يلي:

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

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

ومع ذلك، مع تقديم Streams في Java 8، يمكنك القيام بنفس الشيء بصيغة أقل بكثير.على سبيل المثال، بالنسبة لك someList يمكنك ان تفعل:

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

يمكنك العثور على المزيد حول التدفقات هنا.

كما قال العديد من الإجابات الجيدة، يجب على الكائن تنفيذ 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 حلقة.

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

ال جافا لكل حلقة (المعروف أيضًا باسم حلقة 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.

يمكن اعتبار القولون يعني "في".لذلك ينص إعلان الحلقة المحسّن على ما يلي:قم بالتكرار فوق intArray وقم بتخزين قيمة int للصفيف الحالي في متغير القيمة الحالية

انتاج:

1
3
5
7
9

مثال - صفيف السلسلة

يمكننا استخدام حلقة for-each للتكرار على مجموعة من السلاسل.ينص إعلان الحلقة على ما يلي:قم بالتكرار فوق صفيف سلسلة myStrings وقم بتخزين قيمة السلسلة الحالية في متغير السلسلة الحالية.

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 وقم بتخزين قيمة القائمة الحالية في متغير العنصر الحالي.

انتاج:

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 of Strings وقم بتخزين قيمة المجموعة الحالية في متغير العنصر الحالي.لاحظ أنه بما أن هذه مجموعة، فلا يتم تخزين قيم السلسلة المكررة.

انتاج:

alpha
delta
beta
gamma

مصدر: الحلقات في جافا – الدليل النهائي

لا يمكن تطبيق لغة Java لكل لغة إلا على المصفوفات أو الكائنات من النوع *متوقعة.هذا المصطلح هو ضمني لأنه مدعوم حقًا بواسطة Iterator.تتم برمجة Iterator بواسطة المبرمج وغالبًا ما يستخدم فهرسًا صحيحًا أو عقدة (اعتمادًا على بنية البيانات) لتتبع موضعه.على الورق، فهي أبطأ من حلقة for العادية، على الأقل بالنسبة للهياكل "الخطية" مثل المصفوفات والقوائم ولكنها توفر قدرًا أكبر من التجريد.

هذا يبدو مجنونا ولكن مهلا أنه يعمل

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

هذا يعمل. سحر

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

يتكرر على كافة الكائنات في جدول العناصر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top