Salam! Bu gün Java-da keçid operatorları haqqında danışacağıq:
return
break
continue
goto
if
) və döngələr ( for
, while
və 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. Dö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əreturn
onun çağırıldığı metodu dayandırır və proqramın icrası metodun çağırıldığı yerə qayıdır. Onun return
iki forması var:
- Dərhal metodun icrasını bitirir.
- Metodun icrasını dərhal bitirir və metodun nəticəsi olaraq müəyyən bir dəyəri qaytarır.
return;
return value; // где value — некоторое возвращаемое meaning
return
Də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ə return
qaytarı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 void
ifadənin olması məqbuldur, lakin tələb olunmur . Buna aşağıdakı nümunələrlə baxaq: return
return
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
break
və operatorlarına baxmazdan əvvəl continue
Java-da etiketlər haqqında danışmaq istərdim. Bu vacibdir, çünki bəzi hallarda break
və operatorlar continue
etiketlə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:
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ışı main
aş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ə definePrintName
və 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ə
Operatorbreak
iki halda istifadə olunur:
- Switch-case blokunda hər hansı icra şöbəsini tamamlamaq üçün.
- Döngənin icrasını dayandırmaq üçün.
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Kommutator bloklarında operator break
etiketsiz 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ə break
müə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 break
müə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 break
etiketlə 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 break
etiketi 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
Operatoruncontinue
həmçinin iki forması var - etiketli və etiketsiz:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
break
Döngənin bütün qalan iterasiyalarını kəsən operatordan fərqli olaraq , operator continue
cari iterasiyanı kəsir və növbətinin başlamasına səbəb olur. Müə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 continue
etiketlə 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
break
Operatorların eyni funksionallığa nail olmaq üçün müxtəlif yollarla istifadə oluna biləcəyini continue
söyləməyə dəyər . return
Beləliklə, son nümunəni yenidən yaza və continue
istifadə 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 break
arası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: continue
break
continue
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;
}
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 ( break
və continue
). 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 vargoto
. Tipik olaraq, kodun icrasını proqramın bir etiketlə qeyd olunan hissəsinə yönləndirir. Ancaq Java-da goto
deyə 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ı goto
eyni 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.
goto
kifayə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 . goto
Bə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, goto
bu 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 goto
Java açar sözlər siyahısında qalır, lakin heç bir funksionallıq daşımır. Ola bilsin ki, nə vaxtsa goto
sı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: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.
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.
continue
.- etiketlərlə: müxtəlif yuvaların dövrləri;
- etiketsiz: çağırıldığı döngənin davamı.
goto
.- açar sözlər siyahısındadır, lakin istifadə edilmir.
GO TO FULL VERSION