JavaRush /Java Blogu /Random-AZ /Java-da keçid operatorları

Java-da keçid operatorları

Qrupda dərc edilmişdir
Salam! Bu gün Java-da keçid operatorları haqqında danışacağıq:
  • return
  • break
  • continue
  • goto
Əvvəlcə onun əslində nə olduğunu müəyyən edək. Bildiyiniz kimi, normal vəziyyətdə proqram xətti olaraq - yuxarıdan aşağıya, əmrlə əmrlə yerinə yetirilir. Proqramın xətti axını sözdə idarəetmə strukturları ilə dəyişdirilə bilər: məsələn, budaqlar ( if) və döngələr ( for, whilevə s.). İdarəetmə strukturlarına əlavə olaraq, proqramın xətti icrası keçid ifadələri ilə dəyişdirilə bilər. Onlar proqramın icrasını kontekstdən və konkret bəyanatdan asılı olaraq müəyyən bir yerə yönləndirmək üçün məsuliyyət daşıyırlar. Java-da keçid operatorları - 1Dörd operatorun hər birinə daha yaxından nəzər salaq.

qayıtmaq

Məhz bu operatorla yeni gələnlər tez-tez ilk tanış olurlar. İfadə returnonun çağırıldığı metodu dayandırır və proqramın icrası metodun çağırıldığı yerə qayıdır. Onun returniki forması var:
  1. Dərhal metodun icrasını bitirir.
  2. Metodun icrasını dərhal bitirir və metodun nəticəsi olaraq müəyyən bir dəyəri qaytarır.
Hər iki forma üçün sintaksis belədir:
return;
return value; // где value — некоторое возвращаемое meaning
returnDəyəri qaytaran metodların çağırılmasına zəmanət verilən qaytarma dəyəri olan ən azı bir operatoru olmalıdır və returnqaytarılma dəyəri olmayan operator olmamalıdır. Aşağıdakı nümunələrə baxaq:
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;
    }
}
Dəyəri qaytarmayan metodlarda (metodlar ), qaytarılma dəyəri olan bir ifadənin deyil , ən azı bir qaytarma dəyəri olmayan bir voidifadənin olması məqbuldur, lakin tələb olunmur . Buna aşağıdakı nümunələrlə baxaq: returnreturn
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);
}

etiketlər

breakvə operatorlarına baxmazdan əvvəl continueJava-da etiketlər haqqında danışmaq istərdim. Bu vacibdir, çünki bəzi hallarda breakvə operatorlar continueetiketlərlə birlikdə istifadə olunur. Ancaq əvvəlcə bu kodun tərtib edilib-edilməyəcəyi sualına cavab verməyə çalışın:
public static void main(String[] args) {
    https://www.google.com/
    System.out.println("Interesting...");
}
Etiket adlandırılmış kod parçasıdır. Etiketin özü heç bir funksionallıq təmin etmir. Bu, proqramçının sonradan istifadə etmək niyyətində olduğu koddakı əlfəcin kimi bir şeydir. Koddakı etiket olduqca sadə şəkildə müəyyən edilir - ad və iki nöqtə ilə. Misal üçün:
  • labelName:
  • outerLoop:
  • printing:
  • anyWordYouLike:
Java kodunun içərisində etiketlər belə görünür:
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();
    }
}
Metodun çıxışı mainaşağıdakı kimi olacaq:
Таблица Умножения
   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
Yuxarıdakı nümunədə definePrintNamevə etiketlərdir. və iki dövrü "qeyd edin" - xarici və daxili. Aşağıdakı bölmədə etiketlərin istifadəsinə baxacağıq. Bu arada, bu kodun tərtib edilib-edilməyəcəyi sualına “yox” cavabını versəniz: loop1:loop2:loop1:loop2:
public static void main(String[] args) {
      https://www.google.com/
      System.out.println("Interesting...");
  }
IDE-dən istifadə edərək yenidən cavab verməyə çalışın.

fasilə

Operator breakiki halda istifadə olunur:
  1. Switch-case blokunda hər hansı icra şöbəsini tamamlamaq üçün.
  2. Döngənin icrasını dayandırmaq üçün.
Operatorun iki forması var: işarələrlə (etiket) və olmadan. Hər iki forma üçün sintaksis belədir:
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Kommutator bloklarında operator breaketiketsiz istifadə olunur:
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);
}
Döngələrdə breakmüəyyən şərtlər yerinə yetirildikdən sonra sonrakı təkrarlamaları dayandırmaq üçün bir ifadə istifadə olunur. Bu, tez-tez bir massiv və ya elementlər toplusunu təkrarlamaq və orada lazımi şərtləri təmin edən bəzi elementi tapmaq lazım olduqda tapıla bilər. Bu misalı nəzərdən keçirək. Bizdə massiv var və massivin mənfi elementləri olub-olmadığını müəyyən etməliyik:
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;
   }
}
Fərqli döngələrlə eyni nümunəyə baxaq. Dövr 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;
        }
    }
}
Dövr 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 ++;
    }
}
Dövr 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);
}
Döngələrdəki ifadənin başqa bir nümunəsi breakmüəyyən şərtlərə çatdıqda sonsuz döngəni kəsməkdir. İstifadəçi “dayandır” sözünü daxil edənə qədər istifadəçinin daxil etdiyi sətri əks etdirən bir proqram nümunəsidir:
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);
    }
}
Operatordan breaketiketlə birlikdə istifadə etməyi nəzərdən keçirək. Etiketli kəsmə bir neçə dövrə malik hallarda istifadə olunur, üstəlik, biri digəri içərisindədir. Bu halda, dövrlərdən biri (və ya bütün dövrlər) bir etiketlə qeyd olunur. Sonra operator breaketiketi göstərməklə birlikdə istədiyiniz dövrü kəsir. Massivdə deyil, matrisdə mənfi elementin olub-olmadığını anlamalı olduğumuz bir nümunəyə baxaq:
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;
               }
           }
       }
}

davamlılıq

Operatorun continuehəmçinin iki forması var - etiketli və etiketsiz:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
breakDöngənin bütün qalan iterasiyalarını kəsən operatordan fərqli olaraq , operator continuecari iterasiyanı kəsir və növbətinin başlamasına səbəb olur. Java-da keçid operatorları - 2Müəyyən şərtləri təmin edən elementlər üzərində bəzi əməliyyatlar yerinə yetirmək lazım olduqda bu faydalı ola bilər. Tutaq ki, bir sətirimiz var və biz “m” hərfi ilə başlayan sözlərin sayını saymaq istəyirik:
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);
}
Bu kodu yerinə yetirdikdən sonra konsolda aşağıdakı çıxış olacaq:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
Elementlər üzərində təkrarlama zamanı operator continueetiketlə birlikdə də istifadə olunur. Mənfi elementləri olan cərgələrin sayını saymalı olduğumuz bir matrisi təsəvvür edək:
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);
}
Bu kodun çıxışı belə olacaq:
Rows With Negative Elements Count = 3
breakOperatorların eyni funksionallığa nail olmaq üçün müxtəlif yollarla istifadə oluna biləcəyini continuesöyləməyə dəyər . returnBeləliklə, son nümunəni yenidən yaza və continueistifadə edə bilərsiniz 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);
}
Etiket breakarasındakı fərq, onun yazıldığı döngənin təkrarlarını tamamlayan şeydir. Və bir etiket ilə, etiketlə qeyd olunan dövrün cari iterasiyasını atlar. Bəzi hallarda birini digəri ilə əvəz edə bilərsiniz və proqramın funksionallığında hər şey eyni qalacaq. Seçməyin ən yaxşısı (spoiler: kodun oxunması) haqqında aşağıda danışacağıq. Operator təkcə etiketlə deyil, həm də ilə əvəz edilə bilər . Bundan bir qədər əvvəl, iç-içə döngəni ayrı bir üsula köçürməlisiniz: continuebreakcontinuebreakcontinuereturn
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;
}
Eyni şeyi yazmağın bir çox yolu. Hansı birini seçmək? Sənaye proqramlaşdırmasında bu məsələ kodu başa düşmək asanlığı ilə həll edilir. Nə qədər sadə yazılsa, bir o qədər yaxşıdır. Daha çox yuvalanmış döngələr, kodu qəbul etmək bir o qədər çətindir. Xüsusilə döngələr kəsilmələrdə və davamlarda istifadə olunan müxtəlif etiketlərlə qeyd olunursa ( breakcontinue). Teqlərdən istifadə etməmək mümkünsə, bunu etmək daha yaxşıdır. Əks halda, mümkün qədər aydın və gözəl yazmağa çalışın.

getmək

Bəzi proqramlaşdırma dillərində operator var goto. Tipik olaraq, kodun icrasını proqramın bir etiketlə qeyd olunan hissəsinə yönləndirir. Ancaq Java-da gotodeyə bilər ki, bu var və deyil. Gəlin bunu anlayaq. Java-da açar sözlər siyahısına söz daxildir goto. Bununla belə, bu ifadə istifadə edilməmiş kimi qeyd olunur. Məsələ burasındadır ki, Java dilinin yaradıcısı Ceyms Qoslinq əvvəlcə JVM-də operatorun dəstəyini daxil etmişdi goto. Lakin sonradan bu xüsusiyyət kəsilib. Səbəblərdən biri odur ki, operatoru ehtiva edən kod blokları gotoeyni funksiyaları yerinə yetirən kod blokları kimi oxunaqlı deyildi, lakin - olmadan goto, lakin alternativ yanaşmalarla ( break, continue, kod blokunun metodlarda yerləşdirilməsi). Əslində başqaları da var idi, məsələn:
  • operatorları ehtiva edən kodu oxumaq və anlamaqda çətinlik goto;
  • kompilyator üçün kodun optimallaşdırılmasını çətinləşdirir (və bəzən hətta qeyri-mümkündür);
  • kodda incə xətalar yaratma ehtimalını artırır.
Çoxlarına sirr deyil ki, bəzi proqramlaşdırma dillərində operator gotokifayət qədər uğurla işləyir. Bununla belə, proqramçılar ondan istifadə etməkdən çəkinirlər. Bunun səbəbləri haqqında Habré-də bir məqalədə oxuya bilərsiniz . gotoBəs niyə onu qorunan sözlər siyahısında qoyursunuz ? Bu sadədir: gələcək üçün. Məsələn, bütün dünyada tərtibatçıların Java kodunda dəyişənlər, metodlar və ya siniflər çağırılarsa, gotobu ifadə Java-nın gələcək versiyasında qaytarılarsa, bütün köhnə kod pozulacaq. Belə bir ssenarinin qarşısını almaq üçün gotoJava açar sözlər siyahısında qalır, lakin heç bir funksionallıq daşımır. Ola bilsin ki, nə vaxtsa gotosıralarımıza qayıdacaq, amma bunun ehtimalı azdır.

Nəticələr

Java-da müxtəlif keçid operatorlarına baxdıq:
  1. return— metodun tamamlanması, metoddan dəyərin qaytarılması.
    • qaytarılması dəyəri ilə: dəyərləri qaytaran üsullar;
    • qaytarılma dəyəri yoxdur: voidüsullar.
  2. break— dövrələrin kəsilməsi, kommutator blokları.
    • etiketlərlə: müxtəlif yuvaların dövrləri;
    • etiketsiz: blokun açar qutusu filialları; çağırıldığı döngəni kəsir.
  3. continue.
    • etiketlərlə: müxtəlif yuvaların dövrləri;
    • etiketsiz: çağırıldığı döngənin davamı.
  4. goto.
    • açar sözlər siyahısındadır, lakin istifadə edilmir.
Bütün bunlardan nəticə sadədir: kodun oxunmasını asanlaşdıran ən sadə yanaşmalara üstünlük vermək daha yaxşıdır. Çoxlu işarələr, fasilələr və davamlarla bir-birinin içərisinə daxil edilmiş çoxsəviyyəli döngələrlə kodunuzu çox yükləməməyə çalışın.
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION