هل تشعر بالارتباك في الحلقات المتداخلة؟ لست وحدك!
\n\nتخيل الموقف: أنت تكتب بحثًا في مصفوفة ثنائية الأبعاد، أو تعالج مصفوفة، أو تبحث عن مكررات في قائمة من القوائم. وفجأة تدرك - لا تحتاج فقط إلى قطع الحلقة الداخلية، بل إلى الخروج من كلتيهما مرة واحدة. ألم مألوف؟ إذا كنت قد بحثت في Google مرة واحدة على الأقل عن "how do I break out of nested loops in Java" - فأنت لست وحدك. هذا السؤال جمع مئات الآلاف من المشاهدات على Stack Overflow، وليس من دون سبب: في Java لا يوجد حل بسيط بكلمة مفتاحية واحدة لهذه المهمة.
\n\nفي هذه المقالة، سنستعرض 4 طرق موثوقة للخروج من الحلقات المتداخلة في Java. ستتعرف على سبب عدم عمل break العادي، وكيفية استخدام التسميات (labels) دون الإضرار بسهولة القراءة، ومتى يجب التخلي عن الحلقات تمامًا لصالح حلول أكثر أناقة. هيا بنا!
لماذا لا يحل break البسيط المشكلة؟
\n\nدعنا نذهب مباشرة إلى الموضوع. إليك كودًا نموذجيًا يكتبه المبتدئون:
\n\nint[][] matrix = {\n {1, 2, 3},\n {4, 5, 6},\n {7, 8, 9}\n};\n\nint target = 5;\nboolean found = false;\n\nfor (int i = 0; i < matrix.length; i++) {\n for (int j = 0; j < matrix[i].length; j++) {\n if (matrix[i][j] == target) {\n found = true;\n break; // يخرج فقط من الحلقة الداخلية!\n }\n }\n // الحلقة الخارجية تستمر!\n}\n\nالمشكلة واضحة: الكلمة المفتاحية break في Java تقطع فقط الحلقة التي توجد فيها. الحلقة الخارجية تستمر في العمل، وتفقد السيطرة على المنطق. هذا أحد الأخطاء الأكثر شيوعًا التي تتم مناقشتها في إجابات السؤال "how to break nested loops in Java".
الطريقة رقم 1: استخدام التسميات (labeled break)
\n\nالطريقة الأكثر مباشرة وأصلية هي التسميات (labels). نعم، في Java هناك آلية تشبه goto، لكنها مقيدة بشكل صارم بالعمل مع الحلقات. تبدو كالتالي:
int[][] matrix = {\n {1, 2, 3},\n {4, 5, 6},\n {7, 8, 9}\n};\n\nint target = 5;\nboolean found = false;\n\nouterLoop: // ← تسمية للحلقة الخارجية\nfor (int i = 0; i < matrix.length; i++) {\n for (int j = 0; j < matrix[i].length; j++) {\n if (matrix[i][j] == target) {\n found = true;\n break outerLoop; // ← نخرج من الحلقة الخارجية!\n }\n }\n}\n\nSystem.out.println("تم العثور على: " + found); // true\n\nكيف يعمل هذا:
\n- \n
- نضع تسمية
outerLoop:قبل الحلقة الخارجية (الاسم عشوائي، ولكن حسب الاتفاقية - camelCase أو snake_case). \n - عند تنفيذ
break outerLoop;، ينتقل التحكم إلى السطر الذي يلي الحلقة الخارجية مباشرة. \n
العيب: بعض المطورين يعتبرون التسميات "خدعة قذرة" تقلل من سهولة القراءة. لكن عمليًا، بالنسبة للحلقات المتداخلة البسيطة، هذا نهج طبيعي تمامًا. هذا هو الإجابة الأكثر شيوعًا على Stack Overflow لسؤال "how do I break out of nested loops in Java".
\n\nالطريقة رقم 2: متغير العلم (boolean guard)
\n\nإذا كانت التسميات تبدو غريبة جدًا بالنسبة لك، استخدم العلم الكلاسيكي. الفكرة بسيطة: ننشئ متغيرًا منطقيًا يشير إلى ضرورة الخروج.
\n\nint[][] matrix = {\n {1, 2, 3},\n {4, 5, 6},\n {7, 8, 9}\n};\n\nint target = 5;\nboolean found = false;\n\nfor (int i = 0; i < matrix.length && !found; i++) { // ← التحقق من العلم في الشرط\n for (int j = 0; j < matrix[i].length; j++) {\n if (matrix[i][j] == target) {\n found = true;\n break; // نخرج من الحلقة الداخلية\n }\n }\n // الحلقة الخارجية ستنتهي أيضًا، لأن found == true\n}\n\nSystem.out.println("تم العثور على: " + found);\n\nالمزايا: الكود مفهوم حتى للمبتدئين، ولا يتطلب معرفة بالتسميات.
\nالعيوب: الحلقة الخارجية لا تزال تنفذ تكرارًا إضافيًا (التحقق من الشرط