JavaRush /Java blogi /Random-UZ /Java-da o'tish operatorlari

Java-da o'tish operatorlari

Guruhda nashr etilgan
Salom! Bugun biz Java-da o'tish operatorlari haqida gaplashamiz:
  • return
  • break
  • continue
  • goto
Birinchidan, keling, aslida nima ekanligini aniqlaylik. Ma'lumki, oddiy vaziyatda dastur chiziqli - yuqoridan pastgacha, buyruq bilan bajariladi. Dasturning chiziqli oqimi boshqaruv tuzilmalari deb ataladigan narsalar bilan o'zgartirilishi mumkin: masalan, filiallar ( if) va tsikllar ( for, whileva boshqalar). Boshqaruv konstruksiyalaridan tashqari, dasturning chiziqli bajarilishini o'tish ko'rsatmalari bilan o'zgartirish mumkin. Ular kontekst va maxsus bayonotga bog'liq bo'lgan dasturning bajarilishini ma'lum bir joyga yo'naltirish uchun javobgardir. Java-da o'tish operatorlari - 1Keling, to'rtta operatorning har birini batafsil ko'rib chiqaylik.

qaytish

Aynan shu operator bilan yangi kelganlar birinchi bo'lib tanish bo'lishadi. Bayonot o'zi returnchaqirilgan usulni tugatadi va dasturning bajarilishi usul chaqirilgan joyga qaytadi. U returnikkita shaklga ega:
  1. Usulning bajarilishini darhol tugatadi.
  2. Usulning bajarilishini darhol tugatadi va usul natijasi sifatida ba'zi qiymatlarni qaytaradi.
Ikkala shakl uchun sintaksis:
return;
return value; // где value — некоторое возвращаемое meaning
returnQiymat qaytaruvchi usullar chaqirilishi kafolatlangan qaytish qiymatiga ega kamida bitta operatorga ega bo‘lishi va returnqaytaruvchi qiymati bo‘lmagan operatorga ega bo‘lmasligi kerak. Keling, quyidagi misollarni ko'rib chiqaylik:
public int sum(int a, int b) {
    return a + b;
}

public String getGreetings(String name) {
    return "Hello " + name;
}

public int max(int x, int y) {
    if (x > y) {
        return x;
    } else {
        return y;
    }
}
Qiymat qaytarmaydigan usullarda (metods void) qabul qilinadi, lekin hech bo'lmaganda qaytish qiymati bo'lmagan bitta bayonotga ega bo'lish shart emas , lekin qaytarish qiymati bo'lgan returnbitta bayonot emas . returnKeling, buni quyidagi misollar bilan ko'rib chiqaylik:
public void print(String s) {
    // наличие return в void методах не обязательно
    System.out.println(s);
}

//Метод выведет в консоль число, если оно нечетное
public void printIfOdd(int number) {
    if (number % 2 == 0) {
        // Если число четное, метод завершит свою работу
        // Наличие return в void методах опционально
        return;
    }

    System.out.println(number);
}

// Метод выведет в консоль наибольшее meaning из массива
private void printMaxInArray(int[] array) {
    if (array == null || array.length == 0) {
        /*
         Если массив пуст, метод завершит свою работу.
         Иногда полезно проверять подобным образом аргументы метода вначале и прерывать выполнение метода, если аргументы не подходят для дальнейшей корректной работы
        */
        System.out.println("Empty array");
        return;
    }

    int max = array[1];
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max) {
            max = array[i];
        }
    }
    System.out.println(max);
}

yorliqlar

breakva operatorlarini ko'rib chiqishdan oldin continue, men Java-dagi teglar haqida gapirmoqchiman. Bu juda muhim, chunki ba'zi holatlarda breakva operatorlar continueteglar bilan birgalikda ishlatiladi. Lekin birinchi navbatda, ushbu kod kompilyatsiya qilinadimi degan savolga javob berishga harakat qiling:
public static void main(String[] args) {
    https://www.google.com/
    System.out.println("Interesting...");
}
Yorliq - bu nomlangan kod qismi. Yorliqning o'zi hech qanday funksionallikni ta'minlamaydi. Bu dasturchi keyinchalik ishlatmoqchi bo'lgan koddagi xatcho'pga o'xshaydi. Koddagi yorliq juda oddiy - ism va ikki nuqta orqali aniqlanadi. Masalan:
  • labelName:
  • outerLoop:
  • printing:
  • anyWordYouLike:
Java kodida teglar shunday ko'rinadi:
public static void main(String[] args) {
    definePrintName:
    System.out.println("Таблица Умножения");

    loop1:
    for (int i = 1; i <= 10; i++) {
        loop2:
        for (int j = 1; j <= 10; j++) {
            System.out.printf("%4d", i * j);
        }
        System.out.println();
    }
}
Usulning chiqishi mainquyidagicha bo'ladi:
Таблица Умножения
   1   2   3   4   5   6   7   8   9   10
   2   4   6   8   10  12  14  16  18  20
   3   6   9   12  15  18  21  24  27  30
   4   8   12  16  20  24  28  32  36  40
   5   10  15  20  25  30  35  40  45  50
   6   12  18  24  30  36  42  48  54  60
   7   14  21  28  35  42  49  56  63  70
   8   16  24  32  40  48  56  64  72  80
   9   18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90  100

Process finished with exit code 0
Yuqoridagi misolda definePrintNameva teglar. va ikkita tsiklni "belgilash" - tashqi va ichki. Quyidagi bo'limda teglardan foydalanishni ko'rib chiqamiz. Ayni paytda, agar siz ushbu kod tuziladimi degan savolga "yo'q" deb javob bergan bo'lsangiz: loop1:loop2:loop1:loop2:
public static void main(String[] args) {
      https://www.google.com/
      System.out.println("Interesting...");
  }
IDE-dan foydalanib, yana javob berishga harakat qiling.

tanaffus

Operator breakikki holatda qo'llaniladi:
  1. Kommutator blokidagi har qanday ijro novdasini bajarish uchun.
  2. Loopning bajarilishini to'xtatish uchun.
Operator ikkita shaklga ega: belgilar bilan (yorliq) va bo'lmasdan. Ikkala shakl uchun sintaksis:
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Kommutator bloklarida operator breakteglarsiz ishlatiladi:
public static void main(String[] args) {
    int dayOfWeekInt = 4;
    String dayOfWeek;
    switch (dayOfWeekInt) {
        case 1:
            dayOfWeek = "Monday";
            break;
        case 2:
            dayOfWeek = "Tuesday";
            break;
        case 3:
            dayOfWeek = "Wednesday";
            break;
        case 4:
            dayOfWeek = "Thursday";
            break;
        case 5:
            dayOfWeek = "Friday";
            break;
        case 6:
            dayOfWeek = "Saturday";
            break;
        case 7:
            dayOfWeek = "Sunday";
            break;
        default:
            dayOfWeek = "Неизвестный день";
            break;
    }

    System.out.println("Сегодня " + dayOfWeek);
}
Looplarda breakma'lum shartlar bajarilgandan so'ng keyingi iteratsiyalarni to'xtatish uchun bayonot ishlatiladi. Buni ko'pincha massiv yoki elementlar to'plamini takrorlash va undagi zarur shartlarni qondiradigan elementni topish kerak bo'lganda topish mumkin. Keling, ushbu misolni ko'rib chiqaylik. Bizda massiv bor va massivda manfiy elementlar mavjudligini aniqlashimiz kerak:
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;

for (int i = 0; i < a.length; i++) {
   if (a[i] < 0) {
       /*
        Как только найдется
        хотя бы один отрицательный элемент,
        мы прервем цикл с помощью
        оператора break, потому что
        мы выяснor то, что нас интересовало,
        и дальнейший перебор элементов не имеет смысла.
        */
       arrayHasNegativeElements = true;
       break;
   }
}
Keling, turli xil tsikllar bilan bir xil misolni ko'rib chiqaylik. Tsikl for-each:
public static void main(String[] args) {
    int a[] = {1,2,234,-123,12,-2,312,0,412,433};
    boolean arrayHasNegativeElements = false;

    for (int number : a) {
        if (number < 0) {
            arrayHasNegativeElements = true;
            break;
        }
    }
}
Tsikl while:
public static void main(String[] args) {
    int a[] = {1,2,234,-123,12,-2,312,0,412,433};
    boolean arrayHasNegativeElements = false;

    int counter = 0;
    while (counter < a.length) {
        if (a[counter] < 0) {
            arrayHasNegativeElements = true;
            break;
        }
        counter ++;
    }
}
Tsikl do-while:
public static void main(String[] args) {
    int a[] = {1,2,234,-123,12,-2,312,0,412,433};
    boolean arrayHasNegativeElements = false;

    int counter = 0;
    do {
        if (a[counter] < 0) {
            arrayHasNegativeElements = true;
            break;
        }
        counter ++;
    } while (counter < a.length);
}
Looplardagi bayonotning yana bir misoli, breakma'lum shartlarga erishilganda cheksiz tsiklni uzib qo'yishdir. Bu erda foydalanuvchi "stop" so'zini kiritmaguncha foydalanuvchi tomonidan kiritilgan qatorni ko'rsatadigan dasturga misol:
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String line;

    while (true) {
        line = scanner.nextLine();
        if ("stop".equals(line)){
            /*
             Прерываем бесконечный цикл,
             при достижении
             определенного условия
             */
            break;
        }
        System.out.println("Пользователь ввел: " + line);
    }
}
Keling, operatorni breakteg bilan birgalikda ishlatishni ko'rib chiqaylik. Yorliqli uzilish bir nechta siklli, shuningdek, bir-birining ichiga joylashtirilgan hollarda qo'llaniladi. Bunday holda, tsikllardan biri (yoki barcha tsikllar) yorliq bilan belgilanadi. Keyinchalik, operator breakyorliqni ko'rsatish bilan birga kerakli tsiklni to'xtatadi. Keling, massivda emas, balki matritsada salbiy element mavjudligini tushunishimiz kerak bo'lgan misolni ko'rib chiqaylik:
public static void main(String[] args) {
   int[][] a = {
           {1, 2, 3},
           {-412, 12, 0},
           {1223, 474, -54}
   };

   boolean hasNegative = false;

   searchNegative:
       for (int i = 0; i < a.length; i++) {
           for (int j = 0; j < a[i].length; j++) {
               if (a[i][j] < 0) {
                   /*
                       Если использовать break без метки,
                       тогда прервется вложенный цикл for,
                       но внешний продолжит выполнять свои итерации
                       и поиск продолжится.

                       Поэтому мы "помечаем" внешний цикл меткой `searchNegative`
                       и прерываем внешний цикл оператором break совместно с нужной меткой.
                    */
                   hasNegative = true;
                   break searchNegative;
               }
           }
       }
}

davomiylik

Operator continueshuningdek ikkita shaklga ega - yorliqli va yorliqsiz:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
Operatordan farqli o'laroq break, tsiklning qolgan barcha iteratsiyasini to'xtatadi, operator continuejoriy iteratsiyani to'xtatadi va keyingisini ishga tushiradi. Java-da o'tish operatorlari - 2Agar ma'lum shartlarni qondiradigan elementlarda ba'zi operatsiyalarni bajarish kerak bo'lsa, bu foydali bo'lishi mumkin. Aytaylik, bizda satr bor va biz "m" harfi bilan boshlangan so'zlar sonini hisoblamoqchimiz:
public static void main(String[] args) {
    String sentence = "Мама мыла раму";
    String[] words = sentence.split(" ");

    int mWordsCount = 0;

    for (int i = 0; i < words.length; i++) {
        if ( ! words[i].toLowerCase().startsWith("м")) {
            /*
             Если слово не начинается с буквы м,
             то текущая итерация прервется и цикл
             ПРОДОЛЖИТ выполнение со следующей итерации
             */
            continue;
        }

        mWordsCount ++;
    }

    System.out.println("Кол-во слов, начинающихся с буквы М в предложении: " + "[" + sentence + "] = " + mWordsCount);
}
Ushbu kodni bajargandan so'ng konsolda quyidagi chiqish bo'ladi:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
Operator continueteg bilan birga elementlarni takrorlashda ham ishlatiladi. Keling, manfiy elementlarga ega qatorlar sonini hisoblashimiz kerak bo'lgan matritsani tasavvur qilaylik:
public static void main(String[] args) {
    int[][] a = {
            {1, 23, -1, 23, -12},
            {21, 21, 0, 23, 123, 45},
            {123, 3},
            {123, -5, 4, -3},
            {-1, -2, -3}
    };

    int rowsWithNegativeElementsCount = 0;

    rowsLoop:
    // Проходим по каждой строке
        for (int[] arr : a) {
            for (int number : arr) {
                if (number < 0) {
                    /*
                     Если в текущей строке найдется
                     хотя бы 1 отрицательный элемент,
                     тогда мы увеличим переменную счетчик,
                     и с помощью оператора continue rowsLoop
                     прервем текущую итерацию внешнего цикла и
                     принудительно начнем следующую
                     */
                    rowsWithNegativeElementsCount ++;
                    continue rowsLoop;
                }
            }
        }

    System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
Ushbu kodning chiqishi quyidagicha bo'ladi:
Rows With Negative Elements Count = 3
Aytish joizki, operatorlar break, continueva returnbir xil funktsiyaga erishish uchun turli xil usullarda foydalanish mumkin. Shunday qilib, siz oxirgi misolni qayta yozishingiz va continuefoydalanishingiz mumkin break:
public static void main(String[] args) {
    int[][] a = {
            {1, 23, -1, 23, -12},
            {21, 21, 0, 23, 123, 45},
            {123, 3},
            {123, -5, 4, -3},
            {-1, -2, -3}
    };

    int rowsWithNegativeElementsCount = 0;

    for (int[] arr : a) {
        for (int number : arr) {
            if (number < 0) {
                rowsWithNegativeElementsCount ++;
                break;
            }
        }
    }

    System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
breakYorliq va continueyorliq o'rtasidagi farq u breakyozilgan tsiklning takrorlanishini yakunlaydi. Va continueyorliq bilan, yorliq bilan belgilangan tsiklning joriy iteratsiyasini o'tkazib yuboring. Ba'zi hollarda siz birini boshqasi bilan almashtirishingiz mumkin va dasturning funksionalligidagi hamma narsa bir xil bo'lib qoladi. Quyida nimani tanlash yaxshiroq (spoiler: kodni o'qish qobiliyati) haqida gaplashamiz. Operatorni faqat yorliq bilan breakemas, balki bilan ham almashtirish mumkin . Bundan oldin, ichki halqani alohida usulga o'tkazishingiz kerak: continuereturn
public static void main(String[] args) {
    int[][] a = {
            {1, 23, -1, 23, -12},
            {21, 21, 0, 23, 123, 45},
            {123, 3},
            {123, -5, 4, -3},
            {-1, -2, -3}
    };

    int rowsWithNegativeElementsCount = 0;

    for (int[] arr : a) {
        if (arrayHasNegativeElements(arr)) {
            rowsWithNegativeElementsCount ++;
        }
    }

    System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}

static boolean arrayHasNegativeElements(int[] array) {
    for (int number : array) {
        if (number < 0) {
            return true;
        }
    }

    return false;
}
Xuddi shu narsani yozishning ko'plab usullari. Qaysi birini tanlash kerak? Sanoat dasturlashda bu masala kodni tushunish qulayligi bilan hal qilinadi. Qanchalik sodda yozilsa, shuncha yaxshi. Qanchalik ko'p ichki tsikllar bo'lsa, kodni qabul qilish shunchalik qiyin bo'ladi. Ayniqsa, looplar turli xil teglar bilan belgilangan bo'lsa, ular uzilishlar va davomiyliklarda qo'llaniladi ( breakva continue). Agar teglardan foydalanmaslik mumkin bo'lsa, buni qilish yaxshiroqdir. Aks holda, iloji boricha aniq va chiroyli yozishga harakat qiling.

borish

Ba'zi dasturlash tillarida operator mavjud goto. Odatda u kodning bajarilishini yorliq bilan belgilangan dasturning ba'zi qismiga yo'naltiradi. Ammo Java-da gotoshunday deyish mumkin va u yo'q. Keling, buni aniqlaylik. Java tilidagi kalit so'zlar ro'yxati so'zni o'z ichiga oladi goto. Biroq, bu bayonot ishlatilmagan deb belgilangan. Gap shundaki, Java tilini yaratuvchisi Jeyms Gosling dastlab JVM dagi operatorni qo'llab-quvvatlashni o'z ichiga olgan goto. Biroq, bu xususiyat keyinchalik bekor qilindi. Buning sabablaridan biri shundaki, operatorni o'z ichiga olgan kod bloklari gotobir xil funktsiyalarni bajaradigan kod bloklari kabi o'qilishi mumkin emas edi, lekin bo'lmagan goto, lekin muqobil yondashuvlar ( break, continue, kod blokini usullarga joylashtirish). Aslida, boshqalar ham bor edi, masalan:
  • operatorlarni o'z ichiga olgan kodni o'qish va tushunish qiyinligi goto;
  • kompilyator uchun kodni optimallashtirishni murakkablashtirish (va ba'zan hatto imkonsiz);
  • kodda nozik xatolar yaratish ehtimolini oshirish.
Ko'pchilik uchun sir emaski, ba'zi dasturlash tillarida operator gotojuda muvaffaqiyatli ishlaydi. Biroq, dasturchilar undan foydalanishdan qochishadi. Buning sabablari haqida Habré-dagi bitta maqolada o'qishingiz mumkin . gotoAmmo nega uni zahiradagi so'zlar ro'yxatida qoldirasiz ? Bu oddiy: kelajak uchun. Agar, masalan, o'zgaruvchilar, usullar yoki sinflar butun dunyo bo'ylab ishlab chiquvchilarning Java kodida chaqirilsa, gotobu bayonot Java'ning kelajakdagi versiyasida qaytarilsa, barcha eski kod buziladi. Bunday stsenariyning oldini olish uchun gotou Java kalit so'zlari ro'yxatida qoladi, lekin hech qanday funksiyaga ega emas. Balki bir kun kelib gotou safimizga qaytadi, ammo buning ehtimoli past.

Natijalar

Biz Java-da turli xil o'tish operatorlarini ko'rib chiqdik:
  1. return— usulni yakunlash, usuldan qiymatni qaytarish.
    • qaytish qiymati bilan: qiymatlarni qaytaruvchi usullar;
    • Qaytish qiymati yo'q: voidusullar.
  2. break— sikllarning uzilishi, kommutator bloklari.
    • teglar bilan: turli xil uyalar davrlari;
    • teglarsiz: blokning kalitli shoxlari; chaqirilgan tsiklni uzib qo'yish.
  3. continue.
    • teglar bilan: turli xil uyalar davrlari;
    • teglarsiz: u chaqirilgan halqaning davomi.
  4. goto.
    • kalit so'zlar ro'yxatida, lekin ishlatilmaydi.
Bularning barchasidan xulosa qilish oddiy: kodni o'qishni osonlashtiradigan eng oddiy yondashuvlarga ustunlik berish yaxshiroqdir. Kodingizni ko'p belgilar, uzilishlar va davomlar bilan bir-birining ichiga joylashtirilgan ko'p darajali halqalar bilan ortiqcha yuklamaslikka harakat qiling.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION