Java Language
Podstawowe struktury kontrolne
Szukaj…
Uwagi
Wszystkie struktury kontrolne, o ile nie zaznaczono inaczej, wykorzystują instrukcje blokowe . Są one oznaczone nawiasami klamrowymi {}
.
Różni się to od zwykłych instrukcji , które nie wymagają nawiasów klamrowych, ale mają również sztywne zastrzeżenie, ponieważ pod uwagę brana byłaby tylko linia bezpośrednio po poprzedniej instrukcji.
Dlatego też jest całkowicie poprawne napisanie dowolnej z tych struktur kontrolnych bez nawiasów klamrowych, o ile tylko jedna instrukcja następuje po początku, ale jest to zdecydowanie odradzane , ponieważ może prowadzić do błędnych implementacji lub uszkodzenia kodu.
Przykład:
// valid, but discouraged
Scanner scan = new Scanner(System.in);
int val = scan.nextInt();
if(val % 2 == 0)
System.out.println("Val was even!");
// invalid; will not compile
// note the misleading indentation here
for(int i = 0; i < 10; i++)
System.out.println(i);
System.out.println("i is currently: " + i);
If / Else If / Else Control
if (i < 2) {
System.out.println("i is less than 2");
} else if (i > 2) {
System.out.println("i is more than 2");
} else {
System.out.println("i is not less than 2, and not more than 2");
}
Blok if
będzie działał tylko wtedy, gdy i
ma wartość 1 lub mniej.
Warunek else if
jest sprawdzany tylko wtedy, gdy wszystkie warunki przed nim (w poprzednich else if
konstrukty i element nadrzędny if
konstrukty) zostały przetestowane pod kątem false
. W tym przykładzie warunek else if
będzie sprawdzany tylko wtedy, gdy i
jest większe lub równe 2.
Jeśli jego wynik jest true
, jego blok jest uruchamiany, a wszelkie else
konstrukcje else if
i else
po nim zostaną pominięte.
Jeśli żaden z if
i else if
warunki zostały przetestowane na true
The else
blok na końcu zostanie uruchomione.
Dla pętli
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
Trzy składniki pętli for
(oddzielone przez ;
) to deklaracja / inicjalizacja zmiennej (tutaj int i = 0
), warunek (tutaj i < 100
) oraz instrukcja przyrostowa (tutaj i++
). Deklaracja zmiennej jest wykonywana raz, tak jakby była umieszczona wewnątrz {
przy pierwszym uruchomieniu. Następnie sprawdzany jest warunek, jeśli true
jest, że ciało pętli zostanie wykonane, jeśli false
zostanie przerwany. Zakładając, że pętla będzie kontynuowana, ciało wykona się, a na końcu po osiągnięciu }
instrukcja inkrementacji zostanie wykonana tuż przed ponownym sprawdzeniem warunku.
Nawiasy klamrowe są opcjonalne (można użyć jednego wiersza ze średnikiem), jeśli pętla zawiera tylko jedną instrukcję. Ale zawsze zaleca się stosowanie nawiasów klamrowych, aby uniknąć nieporozumień i błędów.
Elementy pętli for
są opcjonalne. Jeśli logika biznesowa zawiera jedną z tych części, możesz pominąć odpowiedni komponent for
pętli for
.
int i = obj.getLastestValue(); // i value is fetched from a method
for (; i < 100; i++) { // here initialization is not done
System.out.println(i);
}
Struktura for (;;) { function-body }
jest równa pętli while (true)
.
Nested For Loops
Dowolna instrukcja pętli posiadająca wewnątrz inną instrukcję pętli, zwaną pętlą zagnieżdżoną. Ten sam sposób zapętlania z większą liczbą wewnętrznych pętli nazywa się „zagnieżdżony dla pętli”.
for(;;){
//Outer Loop Statements
for(;;){
//Inner Loop Statements
}
//Outer Loop Statements
}
Można zademonstrować zagnieżdżenie dla pętli w celu wydrukowania liczb w kształcie trójkąta.
for(int i=9;i>0;i--){//Outer Loop
System.out.println();
for(int k=i;k>0;k--){//Inner Loop -1
System.out.print(" ");
}
for(int j=i;j<=9;j++){//Inner Loop -2
System.out.print(" "+j);
}
}
Podczas gdy pętle
int i = 0;
while (i < 100) { // condition gets checked BEFORE the loop body executes
System.out.println(i);
i++;
}
A while
działa w pętli, jak długo stan w nawiasach jest true
. Nazywa się to również strukturą „pętli przedtestowej”, ponieważ instrukcja warunkowa musi być spełniona przed każdym wykonaniem głównej pętli.
Nawiasy klamrowe są opcjonalne, jeśli pętla zawiera tylko jedną instrukcję, ale niektóre konwencje stylu kodowania wolą mieć nawiasy klamrowe niezależnie.
zrobić ... podczas gdy Loop
Pętla do...while
while różni się od innych pętli tym, że gwarantuje wykonanie przynajmniej raz . Nazywa się to również strukturą „pętli po teście”, ponieważ instrukcja warunkowa jest wykonywana po treści głównej pętli.
int i = 0;
do {
i++;
System.out.println(i);
} while (i < 100); // Condition gets checked AFTER the content of the loop executes.
W tym przykładzie pętla będzie działać, dopóki nie zostanie wydrukowana liczba 100
(nawet jeśli warunek to i < 100
a nie i <= 100
), ponieważ warunek pętli jest oceniany po wykonaniu pętli.
Z gwarancją co najmniej jednego wykonania możliwe jest deklarowanie zmiennych poza pętlą i inicjowanie ich w środku.
String theWord;
Scanner scan = new Scanner(System.in);
do {
theWord = scan.nextLine();
} while (!theWord.equals("Bird"));
System.out.println(theWord);
W tym kontekście theWord
jest definiowane poza pętlą, ale ponieważ gwarantuje, że ma wartość opartą na jego naturalnym przepływie, theWord
zostanie zainicjowane.
Dla każdego
W Javie 5 i nowszych można stosować pętle dla każdej pętli, znane również jako ulepszone pętle dla:
List strings = new ArrayList();
strings.add("This");
strings.add("is");
strings.add("a for-each loop");
for (String string : strings) {
System.out.println(string);
}
Dla każdej pętli można użyć do iteracji po tablicach i implementacjach interfejsu Iterable
, później zawiera klasy Kolekcje , takie jak List
lub Set
.
Zmienna pętli może być dowolnego typu, który można przypisać z typu źródłowego.
Zmienna pętli dla rozszerzonej pętli for dla Iterable<T>
lub T[]
może być typu S
, jeśli
-
T extends S
- zarówno
T
jak iS
są typami pierwotnymi i można je przypisać bez obsady -
S
jest typem pierwotnym, aT
można przekształcić w typ przypisany doS
po konwersji rozpakowywania. -
T
jest typem pierwotnym i można go przekonwertować naS
poprzez konwersję autoboxing.
Przykłady:
T elements = ...
for (S s : elements) {
}
T. | S. | Kompiluje |
---|---|---|
int [] | długo | tak |
długo[] | int | Nie |
Iterable<Byte> | długo | tak |
Iterable<String> | CharSequence | tak |
Iterable<CharSequence> | Strunowy | Nie |
int [] | Długo | Nie |
int [] | Liczba całkowita | tak |
Jeśli inaczej
int i = 2;
if (i < 2) {
System.out.println("i is less than 2");
} else {
System.out.println("i is greater than 2");
}
Instrukcja if
wykonuje kod warunkowo w zależności od wyniku warunku w nawiasach. Gdy warunek w nawiasach jest prawdziwy, przejdzie do bloku instrukcji if, który jest zdefiniowany przez nawiasy klamrowe, takie jak {
i }
. nawias otwierający, aż nawias zamykający wchodzi w zakres instrukcji if.
Blok else
jest opcjonalny i można go pominąć. Działa, if
instrukcja if
jest false
i nie działa, if
instrukcja if
jest prawdziwa, ponieważ w takim przypadku instrukcja if
wykonywana.
Zobacz także: Trójskładnikowy If
Instrukcja zamiany
Instrukcja switch
jest wielokierunkową gałęzią Javy. Służy do zastąpienia długich łańcuchów, if
- else if
- else
łańcuchami i uczynienia ich bardziej czytelnymi. Jednak w przeciwieństwie do instrukcji if
, nie można używać nierówności; każda wartość musi być konkretnie zdefiniowana.
Istnieją trzy krytyczne elementy instrukcji switch
:
-
case
: Jest to wartość, która jest oceniana pod kątem równoważności z argumentem instrukcjiswitch
. -
default
: Jest to opcjonalne wyrażenie typu catch-all, jeśli żadna z instrukcjicase
niecase
wartościtrue
. - Nagłe uzupełnienie oświadczenia o
case
; zwyklebreak
: Jest to wymagane, aby zapobiec niepożądanej ocenie dalszych stwierdzeńcase
.
Z wyjątkiem continue
możliwe jest użycie dowolnej instrukcji, która spowodowałaby nagłe jej zakończenie . To zawiera:
-
break
-
return
-
throw
W poniższym przykładzie zapisana jest typowa instrukcja switch
z czterema możliwymi przypadkami, w tym default
.
Scanner scan = new Scanner(System.in);
int i = scan.nextInt();
switch (i) {
case 0:
System.out.println("i is zero");
break;
case 1:
System.out.println("i is one");
break;
case 2:
System.out.println("i is two");
break;
default:
System.out.println("i is less than zero or greater than two");
}
Pomijając break
lub jakiekolwiek stwierdzenie, które byłoby nagłym zakończeniem, możemy wykorzystać tak zwane przypadki „przejściowe”, które oceniają na podstawie kilku wartości. Można to wykorzystać do utworzenia przedziałów, w których wartość ma być skuteczna, ale nadal nie jest tak elastyczna jak nierówności.
Scanner scan = new Scanner(System.in);
int foo = scan.nextInt();
switch(foo) {
case 1:
System.out.println("I'm equal or greater than one");
case 2:
case 3:
System.out.println("I'm one, two, or three");
break;
default:
System.out.println("I'm not either one, two, or three");
}
W przypadku foo == 1
wyjście będzie:
I'm equal or greater than one
I'm one, two, or three
W przypadku foo == 3
wyjście będzie:
I'm one, two, or three
Instrukcja switch może być również używana z enum
.
enum Option {
BLUE_PILL,
RED_PILL
}
public void takeOne(Option option) {
switch(option) {
case BLUE_PILL:
System.out.println("Story ends, wake up, believe whatever you want.");
break;
case RED_PILL:
System.out.println("I show you how deep the rabbit hole goes.");
break;
}
}
Instrukcja switch
może być również używana z String
s.
public void rhymingGame(String phrase) {
switch (phrase) {
case "apples and pears":
System.out.println("Stairs");
break;
case "lorry":
System.out.println("truck");
break;
default:
System.out.println("Don't know any more");
}
}
Operator trójskładnikowy
Czasami musisz sprawdzić warunek i ustawić wartość zmiennej.
Np.
String name;
if (A > B) {
name = "Billy";
} else {
name = "Jimmy";
}
Można to łatwo zapisać w jednym wierszu jako
String name = A > B ? "Billy" : "Jimmy";
Wartość zmiennej jest ustawiana na wartość bezpośrednio po warunku, jeśli warunek jest spełniony. Jeśli warunek jest fałszywy, druga wartość zostanie podana zmiennej.
Przerwa
Instrukcja break
kończy pętlę (np. for
, while
) lub ocenę instrukcji switch .
Pętla:
while(true) {
if(someCondition == 5) {
break;
}
}
Pętla w tym przykładzie działałaby wiecznie. Ale gdy someCondition
w pewnym momencie wykonania równa się 5
, pętla się kończy.
Jeśli wiele pętli jest kaskadowanych, tylko najbardziej wewnętrzna pętla kończy się przy użyciu break
.
Spróbuj ... Złap ... Wreszcie
Struktura obsługi try { ... } catch ( ... ) { ... }
służy do obsługi wyjątków .
String age_input = "abc";
try {
int age = Integer.parseInt(age_input);
if (age >= 18) {
System.out.println("You can vote!");
} else {
System.out.println("Sorry, you can't vote yet.");
}
} catch (NumberFormatException ex) {
System.err.println("Invalid input. '" + age_input + "' is not a valid integer.");
}
Spowoduje to wydrukowanie:
Niepoprawne dane wejściowe. „abc” nie jest prawidłową liczbą całkowitą.
Klauzula finally
może zostać dodana po catch
. Klauzula finally
będzie zawsze wykonywana, niezależnie od tego, czy zgłoszony zostanie wyjątek.
try { ... } catch ( ... ) { ... } finally { ... }
String age_input = "abc";
try {
int age = Integer.parseInt(age_input);
if (age >= 18) {
System.out.println("You can vote!");
} else {
System.out.println("Sorry, you can't vote yet.");
}
} catch (NumberFormatException ex) {
System.err.println("Invalid input. '" + age_input + "' is not a valid integer.");
} finally {
System.out.println("This code will always be run, even if an exception is thrown");
}
Spowoduje to wydrukowanie:
Niepoprawne dane wejściowe. „abc” nie jest prawidłową liczbą całkowitą.
Ten kod będzie zawsze uruchamiany, nawet jeśli zostanie zgłoszony wyjątek
Zagnieżdżona przerwa / kontynuacja
Jest to możliwe, aby break
/ continue
do zewnętrznej pętli za pomocą oświadczenia na etykiecie:
outerloop:
for(...) {
innerloop:
for(...) {
if(condition1)
break outerloop;
if(condition2)
continue innerloop; // equivalent to: continue;
}
}
Nie ma innego zastosowania dla etykiet w Javie.
Kontynuuj Instrukcja w Javie
Instrukcja kontynuacji służy do pominięcia pozostałych kroków w bieżącej iteracji i rozpoczęcia od następnej iteracji w pętli. Sterowanie przechodzi od instrukcji continue
do wartości kroku (przyrostu lub zmniejszenia), jeśli istnieje.
String[] programmers = {"Adrian", "Paul", "John", "Harry"};
//john is not printed out
for (String name : programmers) {
if (name.equals("John"))
continue;
System.out.println(name);
}
Instrukcja continue
może również spowodować przesunięcie kontroli programu do wartości kroku (jeśli istnieje) nazwanej pętli:
Outer: // The name of the outermost loop is kept here as 'Outer'
for(int i = 0; i < 5; )
{
for(int j = 0; j < 5; j++)
{
continue Outer;
}
}