We wcześniejszych przykładach stosowałem pętla for do iteracji np. tablicy oraz warunku if-else do podejmowania prze program decyzji na zasadzie logicznych przesłanek (prawda/fałsz). Nie są to jednak jedyne sposoby, aby wykonać pętlę czy sprawdzać warunek logiczny w programie. Jak to często bywa w programowaniu sposobów na otrzymanie tego samego jest bardzo dużo. Alternatywą dla tych instrukcji są na przykład pętla while oraz klauzula switch. Zobacz na program poniżej:
int[] intArray = { 1, 2, 3 }; for (int i = 0; i < intArray.length; i++) { int elementFromArray = intArray[i]; if (elementFromArray == 1) { System.out.println("Wyświetliłeś pierwszy element"); } else if (elementFromArray == 2) { System.out.println("Wyświetliłeś drugi element"); } else { System.out.println("Wyświetliłeś ostatni element"); } }
Pętla while
Użyto tu zwykłej pętli for iterującej tablicę składającej się z trzech elementów. W pętli porównywane są wartości tablicy (wyciągane po indeksie) z odpowiednimi liczbami. Jeśli warunek zajdzie, wyświetlany jest odpowiedni napis. Teraz przepiszę ten kod przy użyciu pętli while. Generalnie zasada tej pętli jest podobna, jednak inkrementacja (i++) tutaj odbywać się będzie w samym ciele pętli, a w nawiasach jedynie jest sprawdzany warunek wyjścia.
int i = 0; while (i < intArray.length) { int elementFromArray = intArray[i]; if (elementFromArray == 1) { System.out.println("Wyświetliłeś pierwszy element"); } else if (elementFromArray == 2) { System.out.println("Wyświetliłeś drugi element"); } else { System.out.println("Wyświetliłeś ostatni element"); } i++; }
Prawda, że proste?
Z reguły będziesz korzystać do iteracji z pętli for, ale są przypadki, w których warto jednak skorzystać z pętli while. Takimi przypadkami są wszelkie iteracje, w których nie wiadomo jak wiele jest elementów. Dobrym przykładem jest czytanie wartości z linii komend. System nie wie, ile parametrów wpisze użytkownik i wypisuje je aż do momentu, gdy użyty zostanie odpowiedni klawisz wyjścia (w podobny sposób działały stare gry na DOS-a!).
Klasa Scanner
Aby wczytać w łatwy sposób parametr sczytany z linii komend, należy użyć klasy Scanner, która opakowuje strumień wejścia (System.in) i udostępnia szereg metod ułatwiających wczytanie wartości do Javy.
Na początku tworzony jest obiekt klasy Scanner. W konstruktorze przekazałem strumień, na jakim chcę pracować (w przypadku strumień wejścia). W nawiasach pętli while wpisuje warunek logiczny, do kiedy pętla ma ‘pracować’. Klasa Scanner przychodzi tu z pomocą i udostępnia metodę hasNext(), która sprawdza czy został jeszcze jakiś parametr w linii komend do sczytania. Jeśli tak, to program wchodzi do pętli i czyta pierwszą napotkaną liczbę do zmiennej nextValue (możemy wczytać też Reszta kodu w pętli while jest identyczna jak w poprzedniej pętli. Na końcu (poza pętlą) należy jeszcze zamknąć strumień metodą close() (jeśli tego nie zrobię strumień aż do momentu zakończenia programu będzie niepotrzebnie otwarty).
Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String nextValue = sc.next(); if (nextValue.equals("1")) { System.out.println("Wyświetliłeś pierwszy element"); } else if (nextValue.equals("2")) { System.out.println("Wyświetliłeś drugi element"); } else { System.out.println("Teraz nastąpi wyjście z programu"); return; } } sc.close();
Mój program ma jednak pewien mankament. Pomimo wczytania wartości nieobsługiwanej, wciąż oczekuje kolejnych parametrów, zamiast się zakończyć po wyświetleniu napisu „Teraz nastąpi wyjście z programu”. Aby na reszcie zakończyć działanie instrukcji while, należy wpisać słowo return, które wyjdzie z niej i będzie kontynuować program poza pętlą.
Switch zamiast if-else
Mój kod mógłbym jeszcze bardziej przerobić używając zamiast warunku if-else, polecenia switch. Działa on prawie tak samo jak w przypadku if-else.
Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int nextInt = scanner.nextInt(); switch (nextInt) { case 1: System.out.println("Wyświetliłeś " + nextInt); break; case 2: System.out.println("Wyświetliłeś " + nextInt); break; default: System.out.println("Liczba poza zakresem"); return; } } sc.close();
W poleceniu switch() wrzucana jest wartość, która program sprawdzi za pomocą instrukcji case. Sam case działa podobnie jak if-else. Aby program dostał się pomiędzy znakiem dwukropka a kolejnym warunkiem wartość wpisana w switchu musi być taka sama jak ta wypisana po słowie case. Jeśli żaden z case’ów nie zostanie spełniony, można napisać sekcję default (tożsame z else) i wpisać tam warunek domyślny.
Break oznacza koniec
Zastanawiasz się pewnie, co oznacza instrukcja break. Dzięki niej switch kończy działanie w pierwszym warunku do jakiego ‘wpadnie’, jeśli ją usuniesz, będzie szukał wszystkich wartości , które mogą spełnić warunek case. Dodatkowo, dla poćwiczenia, wczytaj poprzez Scanner liczby całkowite (metoda nextInt()) zamiast napisów.
Link do lekcji: https://github.com/developeronthego/java-basics/tree/main/src/main/java/basics/lesson12