ב־Java, Label (תווית) הוא שם שמצמידים ללולאה או לבלוק קוד,
כדי לאפשר לפקודות break ו־continue
לפעול על לולאה חיצונית ולא רק על הלולאה הנוכחית.
בדוגמה הבאה ניתן ללולאה החיצונית את השם outer.
כאשר j == 3 מתבצע break outer,
ולכן כל הלולאות נעצרות מיד.
outer:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j == 3) {
break outer;
}
System.out.println(i + ", " + j);
}
}
הפלט:
0, 0
אם היינו משתמשים ב־break רגיל, היינו יוצאים רק מהלולאה הפנימית,
והלולאה החיצונית הייתה ממשיכה לרוץ.
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j == 3) {
break;
}
System.out.println(i + ", " + j);
}
}
הפלט:
0, 0
הפקודה continue מאפשרת לנו לדלג ישירות לאיטרציה הבאה
של לולאה חיצונית.
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) {
continue outer;
}
System.out.println(i + ", " + j);
}
}
הפלט:
0, 0
כאשר j == 1 הלולאה הפנימית מופסקת,
והביצוע קופץ ישירות לאיטרציה הבאה של הלולאה החיצונית.
במקרים מסוימים ניתן לקבל את אותה התוצאה גם באמצעות
break רגיל.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) {
break;
}
System.out.println(i + ", " + j);
}
}
הפלט:
0, 0כאשר עובדים עם מטריצות או עם מספר לולאות מקוננות, Label יכול לחסוך משתני עזר ומתודות נוספות.
נניח שקיימת המטריצה הבאה ואנחנו מחפשים את הערך 5:
int[][] matrix = {
{1,2,3},
{4,5,6},
{7,8,9}
};
באמצעות Label ניתן לצאת מיד מכל הלולאות ברגע שהערך נמצא:
search:
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == 5) {
break search;
}
}
}
ללא Label נצטרך להשתמש במשתנה עזר (Flag):
boolean found = false;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == 5) {
found = true;
break;
}
}
if (found) {
break;
}
}
outer:
for (...) {
for (...) {
for (...) {
if (condition) {
break outer;
}
}
}
}
ללא Label נצטרך לבצע בדיקות חוזרות באמצעות משתנה עזר:
for (...) {
for (...) {
for (...) {
if (condition) {
stop = true;
break;
}
}
if (stop)
break;
}
if (stop)
break;
}
אם קיימת דרך פשוטה וברורה יותר לפתור את הבעיה, עדיף להשתמש בה.
לדוגמה, כאן return הרבה יותר פשוט וברור:
public boolean contains(int[][] arr, int target) {
for (int[] row : arr) {
for (int num : row) {
if (num == target) {
return true;
}
}
}
return false;
}
במקרים רבים ניתן להשתמש ב־Streams בצורה קריאה ופשוטה יותר.
במקום:
boolean found = false;
outer:
for (Integer x : list) {
if (x > 100) {
found = true;
break outer;
}
}
System.out.println(found);
נכתוב:
boolean found =
list.stream()
.anyMatch(x -> x > 100);