JavaRush /Blog Java /Random-MS /Operator Lompat di Jawa

Operator Lompat di Jawa

Diterbitkan dalam kumpulan
hello! Hari ini kita akan bercakap tentang pengendali lompat di Jawa:
  • return
  • break
  • continue
  • goto
Pertama, mari kita tentukan apa sebenarnya. Seperti yang anda ketahui, dalam situasi biasa, program dilaksanakan secara linear - dari atas ke bawah, arahan demi arahan. Aliran linear program boleh diubah oleh apa yang dipanggil struktur kawalan: contohnya, cawangan ( if) dan gelung ( for, whiledll.). Sebagai tambahan kepada konstruk kawalan, pelaksanaan linear program boleh diubah suai dengan pernyataan lompat. Mereka bertanggungjawab untuk mengubah hala pelaksanaan program ke lokasi tertentu, yang bergantung pada konteks dan pernyataan khusus. Operator Lompat dalam Java - 1Mari kita lihat lebih dekat setiap satu daripada empat pengendali.

kembali

Pengendali inilah yang paling kerap dikenali oleh pendatang baru terlebih dahulu. Pernyataan itu returnmenamatkan kaedah di mana ia dipanggil, dan pelaksanaan program kembali ke lokasi dari mana kaedah itu dipanggil. Ia returnmempunyai dua bentuk:
  1. Segera menamatkan pelaksanaan kaedah.
  2. Segera menamatkan pelaksanaan kaedah dan mengembalikan beberapa nilai sebagai hasil kaedah.
Sintaks untuk kedua-dua bentuk ialah:
return;
return value; // где value — некоторое возвращаемое meaning
Kaedah yang mengembalikan nilai mesti mempunyai sekurang-kurangnya satu operator returndengan nilai pulangan yang dijamin untuk dipanggil dan tidak boleh mempunyai operator returntanpa nilai pulangan. Mari lihat contoh di bawah:
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;
    }
}
Dalam kaedah yang tidak mengembalikan nilai (kaedah void), ia boleh diterima, tetapi tidak diperlukan, mempunyai sekurang-kurangnya satu pernyataan returntanpa nilai pulangan, dan bukan satu pernyataan returndengan nilai pulangan. Mari kita lihat ini dengan contoh di bawah:
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);
}

label

Sebelum melihat pada breakdan operator continue, saya ingin bercakap tentang label dalam Java. Ini penting kerana dalam beberapa situasi, breakdan pengendali continuedigunakan bersama dengan label. Tetapi pertama-tama, cuba jawab soalan sama ada kod ini akan disusun:
public static void main(String[] args) {
    https://www.google.com/
    System.out.println("Interesting...");
}
Label ialah sekeping kod bernama. Label itu sendiri tidak menyediakan sebarang fungsi. Ini adalah sesuatu seperti penanda halaman dalam kod yang pengaturcara berhasrat untuk digunakan kemudian. Label dalam kod ditakrifkan dengan mudah - melalui nama dan titik bertindih. Sebagai contoh:
  • labelName:
  • outerLoop:
  • printing:
  • anyWordYouLike:
Dan inilah rupa label di dalam kod Java:
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();
    }
}
Output kaedah mainadalah seperti berikut:
Таблица Умножения
   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
Dalam contoh di atas definePrintName, loop1:dan loop2:ialah label. loop1:dan loop2:"tanda" dua kitaran - luaran dan dalaman. Kami akan melihat menggunakan label dalam bahagian di bawah. Sementara itu, jika anda menjawab "tidak" kepada soalan sama ada kod ini akan disusun:
public static void main(String[] args) {
      https://www.google.com/
      System.out.println("Interesting...");
  }
Cuba jawab sekali lagi, menggunakan IDE.

rehat

Operator breakdigunakan dalam dua kes:
  1. Untuk melengkapkan mana-mana cawangan pelaksanaan dalam blok kotak suis.
  2. Untuk mengganggu perlaksanaan gelung.
Operator mempunyai dua bentuk: dengan tanda (label) dan tanpa. Sintaks untuk kedua-dua bentuk ialah:
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Dalam blok kotak suis, pengendali breakdigunakan tanpa label:
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);
}
Dalam gelung, pernyataan breakdigunakan untuk mengganggu lelaran selanjutnya selepas syarat tertentu dipenuhi. Ini selalunya boleh ditemui apabila anda perlu mengulangi tatasusunan atau koleksi elemen dan mencari beberapa elemen di dalamnya yang memenuhi syarat yang diperlukan. Mari kita pertimbangkan contoh ini. Kami mempunyai tatasusunan dan kami perlu menentukan sama ada tatasusunan mengandungi unsur negatif:
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;
   }
}
Mari kita lihat contoh yang sama dengan gelung yang berbeza. Kitaran 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;
        }
    }
}
Kitaran 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 ++;
    }
}
Kitaran 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);
}
Satu lagi contoh pernyataan breakdalam gelung adalah untuk mengganggu gelung tak terhingga apabila syarat tertentu dipenuhi. Berikut ialah contoh program yang memaparkan baris yang dimasukkan oleh pengguna sehingga pengguna memasukkan perkataan "berhenti":
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);
    }
}
Mari kita pertimbangkan untuk menggunakan operator breakbersama-sama dengan label. Gangguan dengan label digunakan dalam kes dengan beberapa kitaran, lebih-lebih lagi, bersarang satu dalam yang lain. Dalam kes ini, salah satu kitaran (atau semua kitaran) ditandakan dengan label. Seterusnya, pengendali, breakbersama-sama dengan menunjukkan label, mengganggu kitaran yang dikehendaki. Mari kita pertimbangkan contoh di mana kita perlu memahami sama ada terdapat unsur negatif, tetapi tidak dalam tatasusunan, tetapi dalam matriks:
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;
               }
           }
       }
}

kesinambungan

Operator continuejuga mempunyai dua bentuk - dengan dan tanpa label:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
Tidak seperti operator break, yang mengganggu semua baki lelaran gelung, operator continuemengganggu lelaran semasa dan menyebabkan lelaran seterusnya bermula. Operator Lompat dalam Java - 2Ini boleh berguna jika anda perlu melakukan beberapa operasi pada elemen yang memenuhi syarat tertentu. Katakan kita mempunyai rentetan dan kita ingin mengira bilangan perkataan yang bermula dengan huruf "m":
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);
}
Selepas melaksanakan kod ini akan ada output berikut dalam konsol:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
Pengendali continuebersama-sama dengan label juga digunakan apabila melelakan elemen. Mari kita bayangkan matriks di mana kita perlu mengira bilangan baris dengan unsur negatif:
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);
}
Output kod ini ialah:
Rows With Negative Elements Count = 3
Perlu dikatakan bahawa operator break, continuedan returnboleh digunakan dengan cara yang berbeza untuk mencapai fungsi yang sama. Jadi, anda boleh menulis semula contoh terakhir dan continuegunakan 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);
}
Perbezaan antara breakdan continuedengan label ialah perkara yang breakmelengkapkan lelaran gelung di mana ia ditulis. Dan continuedengan label, ia melangkau lelaran semasa kitaran yang ditandakan dengan label. Dalam sesetengah situasi, anda boleh menggantikan satu dengan yang lain, dan segala-galanya dalam fungsi program akan kekal sama. Kami akan membincangkan perkara yang terbaik untuk dipilih (spoiler: kebolehbacaan kod) di bawah. Pengendali breakboleh digantikan bukan sahaja dengan continuelabel, tetapi juga dengan return. Sebelum ini anda perlu mengalihkan gelung bersarang ke kaedah yang berasingan:
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;
}
Banyak cara untuk menulis perkara yang sama. Mana satu nak pilih? Dalam pengaturcaraan industri, isu ini diputuskan oleh kemudahan memahami kod. Lebih mudah ia ditulis, lebih baik. Lebih banyak gelung bersarang, lebih sukar untuk melihat kod tersebut. Terutama jika gelung ditandakan dengan tanda yang berbeza, yang digunakan dalam gangguan dan kesinambungan ( breakdan continue). Sekiranya mungkin untuk tidak menggunakan tag, lebih baik berbuat demikian. Jika tidak, cuba tulis sejelas dan secantik mungkin.

pergi ke

Dalam sesetengah bahasa pengaturcaraan terdapat operator goto. Biasanya ia mengubah hala pelaksanaan kod ke beberapa bahagian program yang ditandakan dengan label. Tetapi dalam Java goto, seseorang mungkin berkata, ia adalah dan ia tidak. Mari kita fikirkan. Senarai kata kunci dalam Java termasuk perkataan goto. Walau bagaimanapun, kenyataan ini ditandakan sebagai tidak digunakan. Hakikatnya ialah James Gosling, pencipta bahasa Java, pada mulanya menyertakan sokongan untuk pengendali dalam JVM goto. Walau bagaimanapun, ciri ini kemudiannya telah dipotong. Salah satu sebabnya ialah blok kod yang mengandungi operator gototidak boleh dibaca seperti blok kod yang menjalankan fungsi yang sama tetapi tanpa goto, tetapi dengan pendekatan alternatif ( break, continue, meletakkan blok kod dalam kaedah). Terdapat, sebenarnya, yang lain, seperti:
  • kesukaran membaca dan memahami kod yang mengandungi operator goto;
  • merumitkan pengoptimuman kod untuk pengkompil (dan kadangkala mustahil);
  • meningkatkan kemungkinan mencipta ralat halus dalam kod.
Bukan rahsia bagi ramai bahawa dalam beberapa bahasa pengaturcaraan pengendali gotoberfungsi dengan jayanya. Walau bagaimanapun, pengaturcara mengelak menggunakannya. Anda boleh membaca tentang sebab untuk ini dalam satu artikel mengenai Habré . Tetapi mengapa kemudian meninggalkannya gotodalam senarai perkataan terpelihara? Ia mudah: untuk masa depan. Jika, sebagai contoh, pembolehubah, kaedah atau kelas dipanggil , dalam kod Java pembangun di seluruh dunia goto, jika pernyataan ini dikembalikan dalam versi Java yang akan datang, semua kod lama akan rosak. Untuk mengelakkan senario sedemikian, gotoia kekal dalam senarai kata kunci Java, tetapi tidak membawa sebarang fungsi. Mungkin suatu hari nanti gotodia akan kembali ke barisan kami, tetapi kemungkinan ini adalah rendah.

Keputusan

Kami telah melihat pelbagai operator lompat di Jawa:
  1. return— penyelesaian kaedah, mengembalikan nilai daripada kaedah.
    • dengan nilai pulangan: kaedah yang mengembalikan nilai;
    • tiada nilai pulangan: voidkaedah.
  2. break— gangguan kitaran, blok kotak suis.
    • dengan tag: kitaran pelbagai sarang;
    • tanpa label: cawangan kes suis blok; mengganggu gelung di mana ia dipanggil.
  3. continue.
    • dengan tag: kitaran pelbagai sarang;
    • tanpa label: kesinambungan gelung di mana ia dipanggil.
  4. goto.
    • berada dalam senarai kata kunci, tetapi tidak digunakan.
Kesimpulan daripada semua ini adalah mudah: adalah lebih baik untuk memberi keutamaan kepada pendekatan paling mudah yang menjadikan kod lebih mudah dibaca. Cuba untuk tidak membebankan kod anda dengan gelung berbilang peringkat yang bersarang di dalam satu sama lain dengan banyak tanda, gangguan dan kesinambungan.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION