حلقة for-each المحسّنة
حلقة for-each المحسّنة
حلقة for التقليدية قوية، لكنها تحمل كودًا مكررًا: تُعلن عن عداد، وتقارنه بالطول، وتزيده — فقط لتزور كل عنصر. تقدم Java بديلًا أنظف يُسمى حلقة for المحسّنة (وتُعرف أيضًا بـ حلقة for-each). صُمِّمت لوظيفة واحدة تحديدًا: التكرار على كل عنصر في مصفوفة أو مجموعة، دون إدارة فهرس على الإطلاق.
البنية العامة
البنية مقصودةً في بساطتها:
اقرأ النقطتين : بمعنى "في". فعبارة for (String name : names) تُقرأ: "لكل String اسمه name في names". تتكفّل Java بجلب كل عنصر والتوقف في النهاية — لا تفعل شيئًا إضافيًا.
التكرار على مصفوفة
إليك المهمة ذاتها مكتوبةً أولًا بحلقة for التقليدية ثم بحلقة for-each، لترى الفرق:
كلتاهما تطبع:
نسخة for-each لا تحتوي على متغير فهرس، ولا مقارنة طول، ولا [i]. يقول الكود ما يعنيه تمامًا: "لكل فاكهة، اطبعها".
التكرار على قائمة List
تعمل for-each مع أي كلاس ينفّذ واجهة Iterable، وهذا يشمل جميع مجموعات Java القياسية مثل ArrayList وLinkedList وHashSet:
التكرار على مجموعة Set
تعمل for-each بالطريقة ذاتها مع Set. الفرق أن Set لا يضمن ترتيبًا معينًا، فقد تظهر العناصر بأي تسلسل:
متى لا تكون for-each مناسبة
تتميّز for-each في الاجتياز للقراءة، لكن لها قيود حقيقية. يجب استخدام حلقة for التقليدية (أو نهج آخر) عندما:
- تحتاج إلى الفهرس. لا تمنحك for-each أي معلومة عن الموضع. إذا أردت طباعة "العنصر 0 هو Apple"، فأنت بحاجة إلى
i. - تحتاج إلى تعديل عنصر مصفوفة. تعيين قيمة لمتغير الحلقة لا يغيّر المصفوفة الأصلية:
for التقليدية بفهرس إذا احتجت تحديث العناصر في مكانها.
- تحتاج إلى التكرار على مصفوفتين في وقت واحد. تعمل for-each على مجموعة واحدة في كل مرة. إذا أردت مقارنة مصفوفتين أو دمجهما عنصرًا بعنصر، فأنت بحاجة إلى فهرس.
- تحتاج إلى التكرار بالعكس. تسير for-each دائمًا للأمام من أول عنصر إلى آخره. لا يوجد وضع عكسي.
- تحتاج إلى حذف عناصر من مجموعة أثناء التكرار. الحذف من
Listداخل for-each يُطلقConcurrentModificationException. استخدمIteratorأوremoveIf()بدلًا من ذلك.
for التقليدية حالما تحتاج إلى فهرس، أو تكرار عكسي، أو تعديل في مكانه.
for-Each مع المصفوفات متعددة الأبعاد
يمكنك تداخل حلقتي for-each لاجتياز مصفوفة ثنائية الأبعاد. الحلقة الخارجية تمنحك كل صف (وهو مصفوفة بحد ذاته)، والحلقة الداخلية تمنحك كل عنصر في ذلك الصف:
الناتج:
الخلاصة
تُزيل حلقة for-each المحسّنة فوضى إدارة الفهارس وتجعل كود التكرار أسهل قراءة. استخدمها بحرية عندما تريد زيارة كل عنصر في مصفوفة أو مجموعة بالترتيب. تذكّر قيودها — لا فهرس، ولا تعديل مباشر لعناصر المصفوفة، ولا تكرار عكسي — وانتقل إلى حلقة for التقليدية متى انطبق أيٌّ من تلك القيود.