Informacje o nowych artykułach oraz akcjach edukacyjnych prosto na Twojej skrzynce e-mail!

Elementarz Java #5 – Pętle

Wstęp

Dzisiaj w ramach cyklu #ElementarzJava artykuł na temat pętli. Proste zagadnienie ale jak zwykle mam nadzieję, że i tym razem czymś Ciebie zaskoczyłem. Zapraszam do dalszej lektury i jak zwykle pozostaje mi życzyć owocnej nauki.

Tworzenie oraz użycie pętli while

Pętla while używana jest do wykonywania zestawu instrukcji do momentu, kiedy podany warunek logiczny nie osiągnie wartości false. Pętla ta sprawdza podany warunek przed rozpoczęciem działania. 

Jak wygląda pętla while

boolean condition = true;

while(condition) {
     System.out.println("Hello");
     conditione = false;
}

Jeśli w pętli mamy tylko jedną instrukcję nawiasy klamrowe mogą zostać pominięte.

boolean condition = true;
while(condition)
     System.out.println("Hello");

Powyższa pętla będzie działać w „nieskończoność”. 

Tworzenie oraz użycie pętli for

W Javie wyróżniamy dwie wersje pętli iteracyjnej for, tradycyjną oraz pętlę for-each. Tradycyjna pętla for jest zazwyczaj używana do wykonywania zestawu poleceń określoną liczbę razy. Składa się ona z trzech instrukcji oddzielonych średnikami: inicjalizacji, warunku zakończenia oraz klauzuli aktualizującej. Definicja każdej z tych trzech instrukcji jest opcjonalna. Poniższy kod będzie więc całkowicie poprawny.

for(;;) { }

Również zdefiniowanie choćby tylko jednej z tych instrukcji nie będzie powodowało błędu. 

int i = 0;
for(;i<1;) {
     System.out.print(i);
     i++;
}

Ten kod zadziała poprawnie i wypisze na ekran cyfrę 0. Jeśli dodatkowo warunek w bloku for został by zmieniony na i<0 to wtedy pętla nie została by wykonana ani razu. Warunek ten sprawdzany jest przed każdym wywołaniem for.

Co ciekawe w bloku inicjalizacyjnym pętli for możemy inicjalizować więcej niż jedną wartość. Zasada jest tutaj jedna, zmienne muszą być tego samego typu.

for(int i = 0, y = 1;i<2;i++) {
     System.out.println(y);
}

Po uruchomieniu powyższego kodu na ekranie komputera dwukrotnie zostanie wypisana wartość zmiennej y czyli liczba 1. Dodatkowo, każda zmienna zdefiniowana w bloku inicjalizującym pętli for, może być również aktualizowana w klauzuli aktualizującej.

for(int i = 0, y = 2;i< 2;i++, y--) {
     System.out.println(y);
}

Taki kod wypisze na ekranie liczbę 2 i 1.

Warunek logiczny jaki umieszczamy w pętli for może być również nieco bardziej rozbudowany. 

int j = 0;
for(int i = 0;i<1 && j<2; ++i) {
     ++j;
     System.out.println("i  = " + i + ", j = " + j);
}

Otrzymamy: i = 0, j = 1

Jak wspomniałem na początku. Java oferuje również drugą wersję pętli for (znanej pod nazwą: enhanced for). Jest ona znacznie prostsza w implementacji, a jej głównym zastosowaniem jest iteracja po kolekcjach. Ważne jest jednak to, że w tej wersji pętli for nie możemy inicjalizować ani modyfikować tablic, usuwać elementów z kolekcji oraz iterować po wielowymiarowych strukturach. Popatrzmy na przykład.

List<Integer> list = ArrayList<Integer>();
list.add(10);
 
for(int x : list) {
     System.out.println(x);
}

Tak w prosty sposób możemy iterować się po różnego rodzaju kolekcjach. Pamiętajmy jednak, że po lewej stronie wyrażenia w pętli musimy mieć podany typ danych jaki wykorzystywany jest w iterowanej kolekcji. Ja w przykładzie podałem int, ale jak już pewnie wiesz, z materiału na temat typów danych, nie ma to znaczenia, bo zadziała mechanizm zwany unboxing’iem. 

Tworzenie oraz użycie pętli do/while

Pętla do-while od pętli while różni się w zasadzie tylko tym, że jej warunek sprawdzany jest na końcu, a nie na jej początku. Oznacza to tyle, że instrukcje umieszczone w ciele pętli do-while zawsze przynajmniej raz zostaną wykonane. 

do {
     System.out.println("Hello");
} while(false);

Tak samo jak w przypadku pętli while lub for w przypadku, kiedy mamy pojedynczą instrukcję umieszczoną w pętli, możemy pominąć nawiasy klamrowe.

do 
     System.out.println("Hello");
while(false);

Porównywanie różnych rodzajów pętli

Zarówno pętla do-while i while wykonują zestawy instrukcji do momentu, kiedy warunek logiczny nie osiągnie wartości false. Jest tylko jedna różnica między nimi. Pętla do-while wykonuje instrukcje, a dopiero później sprawdza warunek. W pętli while to warunek jest sprawdzany najpierw. 

Uproszczona pętla for jest znacznie łatwiejsza w użyciu, ale ma mniej zastosowań. Nie może być używana do inicjalizacji tablic, modyfikacji elementów kolekcji oraz ich usuwania. Nie jest możliwe również iterowanie po wielowymiarowych strukturach danych. Rekomendowane jest wykorzystywanie pętli for, kiedy z góry znamy liczbę iteracji (na przykład w przypadku tablic). W innym przypadku wskazane jest zastosowanie pętli do-while oraz while

Użycie break oraz continue

Słowo kluczowe break używa się do natychmiastowego przerwania wykonywania pętli lub konstrukcji switch. Słowo kluczowe continue jest używane do pominięcia kolejnych instrukcji w danej iteracji pętli i rozpoczęcia kolejnej. Kiedy użyjemy słówko break lub w pętli zagnieżdżonej to przeskoczymy do pętli nadrzędnej. W przypadku continue, pominiemy dalsze instrukcje i przejdziemy do kolejnej iteracji w tej samej pętli (lub też przeskoczymy do pętli nadrzędnej, jeśli pominięta iteracja była ostatnia).

loop1: for(int i = 0;i<2;i++) {
     for(int j = 0;j<3;j++) {
          if(j == 1) {
               continue loop1;
          }
          System.out.println(i + " " + j);
     }
}

Powyższy kod wypisze na ekranie: 0 0, 1 0. Instrukcja continue loop1; w momencie uruchomienia (po spełnieniu warunku logicznego w if) będzie przeskakiwała do pętli loop1 (na temat etykiet piszę nieco niżej). Gdyby nie używać tutaj etykiety, to continue po prostu pominęło by drugą iterację w pętli zagnieżdżonej i przeszło do kolejnej. Na wyjściu mieli byśmy wtedy: 0 0, 0 2, 1 0, 1 2. Instrukcja continue loop1; w pętli zagnieżdżonej oznacza po prostu „kontynuuj pętlę loop1”. 

Gdyby w podanym przykładzie zamiast continue zastosować słówko break: break loop1; to spowodowało by to po pierwsze, pominięcie kolejnych instrukcji w pętli zagnieżdżonej oraz zakończenie wykonywania pętli loop1 (instrukcja break loop1; oznacza „przerwij pętlę loop1”). Użycie samego break („przerwij pętlę zagnieżdżoną”) przerywało by jedynie wykonywanie pętli zagnieżdżonej i przejście o poziom wyżej do kolejnej iteracji pętli loop1. Popatrzmy na krótki przykład.

int count = 0;

loop1: for(int i = 0; i<3; i++) {
     for(int j = 0; j<2 ; j++) {
          if(j == 1) continue loop1;
          count++;
     }
}

System.out.print(count);

Jakie będzie wyjście takiego programu? Odpowiedź to: 3. Zauważmy, że pętla zagnieżdżona dla każdej iteracji pętli zewnętrznej będzie wykonywała instrukcję count++; tylko raz. Przy drugiej próbie za każdym razem zadziała continue loop1; czyli będziemy przechodzili do pętli loop1 i rozpoczynali kolejną iterację.

Etykiety

Java umożliwia dodawanie etykiet do bloków kodu zdefiniowanych za pomocą nawiasów klamrowych, wszystkich konstrukcji pętli (whiledo-whileforfor-each), konstrukcji warunkowych (if i switch), wyrażeń przypisania, instrukcji return oraz bloków try i instrukcji throw.

public static void main(String[] args) throws Exception {
     itIsBlock: { String myLocalVariable = "Hello"; }
     int a = 0;
     itIsLoop: for(;a<0;) { }
     itIsSecondLoop: do { } while(a != 0);
     itIsNewValue: a = 1;
     itIsConditionStatements: if(a != 1) { }
     itIsSwichStatements: switch (a) { }
     itIsTryBlock: try {
          itIsThrowInstruction: throw new Exception();
     } finally {
          itIsReturnStatements: return;
     }
}

Spodobało się?

Jeśli tak, to zarejestruj się do newslettera aby otrzymywać informacje nowych artykułach oraz akcjach edukacyjnych. Gwarantuję 100% satysfakcji i żadnego spamowania!

, , , , , , , , , , , , , , ,

Dodaj komentarz

Komentarze (2)

Odpowiedz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Pin It on Pinterest