JavaRush /Java Blog /Random-TL /Tumalon Operator sa Java

Tumalon Operator sa Java

Nai-publish sa grupo
Kamusta! Ngayon ay pag-uusapan natin ang tungkol sa mga operator ng pagtalon sa Java:
  • return
  • break
  • continue
  • goto
Una, tukuyin natin kung ano talaga ito. Tulad ng alam mo, sa isang normal na sitwasyon, ang isang programa ay isinasagawa nang linear - mula sa itaas hanggang sa ibaba, utos sa pamamagitan ng utos. Ang linear na daloy ng isang programa ay maaaring baguhin ng tinatawag na mga istruktura ng kontrol: halimbawa, mga sanga ( if) at mga loop ( for, whileatbp.). Bilang karagdagan sa mga control construct, ang linear execution ng isang program ay maaaring mabago sa pamamagitan ng jump statement. Responsable sila sa pag-redirect ng pagpapatupad ng programa sa isang partikular na lokasyon, na nakadepende sa konteksto at sa partikular na pahayag. Операторы перехода в Java - 1Tingnan natin ang bawat isa sa apat na operator.

bumalik

Ito ang operator na kadalasang nagiging pamilyar sa mga bagong dating. Tinatapos ng pahayag returnang pamamaraan kung saan ito tinawag, at ang pagpapatupad ng programa ay babalik sa lokasyon kung saan tinawag ang pamamaraan. Ito returnay may dalawang anyo:
  1. Agad na tinapos ang pagpapatupad ng pamamaraan.
  2. Agad na tinapos ang pagpapatupad ng pamamaraan at nagbabalik ng ilang halaga bilang resulta ng pamamaraan.
Ang syntax para sa parehong mga form ay:
return;
return value; // где value — некоторое возвращаемое meaning
Ang mga pamamaraan na nagbabalik ng isang halaga ay dapat na mayroong kahit isang operator returnna may isang return value na garantisadong matatawag, at hindi dapat mayroong operator returnna walang return value. Tingnan natin ang mga halimbawa sa ibaba:
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;
    }
}
Sa mga pamamaraan na hindi nagbabalik ng isang halaga (mga pamamaraan void), ito ay katanggap-tanggap, ngunit hindi kinakailangan, na magkaroon ng hindi bababa sa isang pahayag returnna walang return value, at hindi isang solong pahayag returnna may return value. Tingnan natin ito sa mga halimbawa sa ibaba:
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);
}

mga label

Bago tingnan ang breakat operator continue, gusto kong pag-usapan ang tungkol sa mga label sa Java. Mahalaga ito dahil sa ilang sitwasyon, breakat continueginagamit ang mga operator kasabay ng mga label. Ngunit una, subukang sagutin ang tanong kung ang code na ito ay mag-compile:
public static void main(String[] args) {
    https://www.google.com/
    System.out.println("Interesting...");
}
Ang label ay isang pinangalanang piraso ng code. Ang label mismo ay hindi nagbibigay ng anumang pag-andar. Ito ay tulad ng isang bookmark sa code na nilalayon ng programmer na gamitin sa ibang pagkakataon. Ang isang label sa code ay tinukoy nang simple - sa pamamagitan ng isang pangalan at isang tutuldok. Halimbawa:
  • labelName:
  • outerLoop:
  • printing:
  • anyWordYouLike:
At ito ang hitsura ng mga label sa loob ng Java code:
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();
    }
}
Ang output ng pamamaraan mainay ang mga sumusunod:
Таблица Умножения
   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
Sa halimbawa sa itaas definePrintName, loop1:at loop2:mga label. loop1:at loop2:"markahan" ang dalawang cycle - panlabas at panloob. Titingnan natin ang paggamit ng mga label sa seksyon sa ibaba. Pansamantala, kung sumagot ka ng "hindi" sa tanong kung mag-compile ang code na ito:
public static void main(String[] args) {
      https://www.google.com/
      System.out.println("Interesting...");
  }
Subukang sagutin itong muli, gamit ang IDE.

pahinga

Ang operator breakay ginagamit sa dalawang kaso:
  1. Upang kumpletuhin ang anumang sangay ng pagpapatupad sa isang bloke ng switch-case.
  2. Upang matakpan ang pagpapatupad ng isang loop.
Ang operator ay may dalawang anyo: may mga marka (label) at wala. Ang syntax para sa parehong mga form ay:
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
В блоках switch-case оператор break используется без меток:
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);
}
В циклах оператор break используют для прерывания дальнейших итераций после того, How достигнуты определенные условия. Часто такое можно встретить, когда необходимо перебрать массив or коллекцию элементов и найти в ней Howой-то элемент, удовлетворяющий нужным условиям. Рассмотрим такой пример. У нас есть массив и нам необходимо определить, содержит ли массив отрицательные элементы:
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;
   }
}
Рассмотрим тот же пример с различными циклами. Цикл 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;
        }
    }
}
Цикл 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 ++;
    }
}
Цикл 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);
}
Еще одним примером оператора break в циклах является прерывание бесконечного цикла при достижении определенных условий. Приведем пример программы, выводящей строку, которую ввел пользователь до тех пор, пока юзер не введёт слово “stop”:
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);
    }
}
Рассмотрим использование оператора break совместно с меткой. Прерывание с меткой используется в случаях с несколькими циклами, причем вложенными один в другой. В таком случае один из циклов (or же все циклы) помечается меткой. Далее оператор break совместно с указанием метки прерывает нужный цикл. Рассмотрим пример, в котором нам необходимо понять, есть ли отрицательный элемент, но только не в массиве, а в матрице:
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;
               }
           }
       }
}

сontinue

У оператора continue также есть две формы — с меткой и без:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
В отличии от оператора break, который прерывает все оставшиеся итерации цикла, оператор continue прерывает текущую итерацию и приводит к запуску следующей.Операторы перехода в Java - 2Такое может быть полезно, если нужно провести некоторые операции над elementми, которые удовлетворяют определенным условиям. Скажем, у нас есть строка, и мы хотим посчитать количество слов, начинающихся с буквы “м”:
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);
}
После выполнения данного codeа будет такой вывод в консоли:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
Оператор continue совместно с меткой также используется при переборе элементов. Представим себе матрицу, в которой нам нужно посчитать количество строк с отрицательными elementми:
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);
}
Выводом данного codeа будет:
Rows With Negative Elements Count = 3
Стоит сказать, что операторы break, continue и return можно по-разному использовать для достижения одной и той же функциональности. Так, можно переписать последний пример и instead of continue использовать 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);
}
Difference между break и continue с меткой заключается в том, что break завершает итерации цикла, в котором он написан. А continue с меткой пропускает текущую итерацию цикла отмеченного меткой. В некоторых ситуациях можно заменять одно на другое, и в функциональности программы все останется прежним. О том, что лучше выбрать (спойлер: читаемость codeа), расскажем немного ниже. Оператор break можно заменить не только на continue с меткой, но и на return. Только перед этим нужно вынести вложенный цикл в отдельный метод:
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;
}
Уйма способов написать одно и то же. Какой же выбрать? В промышленном программировании в этом вопросе решает легкость восприятия codeа. Чем проще написано, тем лучше. Чем больше вложенных циклов, тем сложнее воспринимать code. Особенно если циклы отмечены различными метками, которые используются в прерываниях и продолжениях (break и continue). Если есть возможность не использовать метки, лучше так и делать. В ином случае старайтесь писать максимально понятно и красиво.

goto

В некоторых языках программирования существует оператор goto. Обычно он перенаправляет выполнение codeа в Howую-либо часть программы, помеченную меткой. Но в Java goto, можно сказать, и есть, и нет. Давайте разбираться. Список ключевых слов в Java включает слово goto. Однако данный оператор помечен How not used (не используется). Дело в том, что Джеймс Гослинг, создатель ЯП Java изначально заложил в JVM поддержку оператора goto. Однако впоследствии эту фичу выпorли. Одна из причин заключается в том, что блоки codeа содержащие оператор goto, читались не так хорошо, How блоки codeа, выполняющие те же функции, но без goto, а с альтернативными подходами (break, continue, вынесение блока codeа в методы). Были, собственно и другие, How например:
  • сложность чтения и понимания codeа, в котором есть операторы goto;
  • усложнение оптимизации codeа компилятору (а иногда и невозможность);
  • повышение вероятности создания трудно уловимых ошибок в codeе.
Для многих не секрет, что в некоторых языках программирования оператор goto вполне успешно функционирует. Однако программисты избегают его использование. Почитать о причинах этого можно в одной статье на хабре. Но зачем тогда оставлять goto в списке зарезервированных слов? Все просто: на будущее. Если, к примеру, по всему миру в codeе Java разработчиков переменные, методы or классы будут называться goto, если этот оператор вернут в одной из будущих версий Java, весь старый code сломается. Whatбы избежать такого сценария, goto остался в списке ключевых слов Java, но не несет в себе ниHowой функциональности. Возможно когда-нибудь goto вернется в наши ряды, но вероятность этого невысока.

Итоги

Мы рассмотрели различные операторы перехода в Java:
  1. return — завершение метода, возвращение значения из метода.
    • с возвращаемым meaningм: методы, которые возвращают значения;
    • без возвращаемого значения: void методы.
  2. break — прерывание циклов, switch-case блоки.
    • с метками: циклы различной вложенности;
    • без меток: ветки switch-case блока; прерывание цикла, в котором был вызван.
  3. continue.
    • с метками: циклы различной вложенности;
    • без меток: продолжение цикла, в котором был вызван.
  4. goto.
    • есть в списке ключевых слов, но не используется.
Вывод из всего этого простой: лучше отдавать предпочтение наиболее простым подходам, которые облегчают читаемость codeа. Старайся не перегружать code многоуровневыми циклами, вложенными друг в друга с обorем меток, прерываний и продолжений.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION