while-silmukka toistaa tiettyä koodia niin kauan, kuin haluttu ehto pitää paikkansa.
Silmukan rakenne on seuraava:
while ([ehto]) { [koodi] }
Seuraava ohjelma tulostaa luvut väliltä 1–10 while-silmukan avulla:
int luku = 1; while (luku <= 10) { System.out.println(luku); luku = luku + 1; }
Ohjelman tulostus on seuraava:
1 2 3 4 5 6 7 8 9 10
Tässä muuttuja luku
on aluksi 1. Silmukan jokaisella
kierroksella ohjelma tulostaa muuttujan luku
ja kasvattaa sen
arvoa yhdellä. Silmukka jatkuu niin kauan, kuin muuttujan luku
arvo on korkeintaan 10.
Nyt on tullut aika esitellä uusi Javan tietotyyppi. Totuusarvo on
tyyppi, jolla on vain kaksi mahdollista arvoa: true
(tosi) ja
false
(epätosi).
Totuusarvoja on jo käytetty paljon, vaikka niitä ei ole mainittu nimeltä. Kaikki ehdot if-rakenteessa ja silmukoissa ovat nimittäin totuusarvoja.
Totuusarvotyypin tunnus on boolean
. Totuusarvoja voi käsitellä
samaan tapaan kuin merkkijonoja ja lukuja, kuten seuraava ohjelma
havainnollistaa:
boolean salasanaOikein = salasana.equals("kissa"); if (salasanaOikein) { System.out.println("Salasana on oikein!"); }
Tässä muuttuja salasanaOikein
saa arvon true
, jos
salasana on kissa, ja muuten arvon false
. Tämän jälkeen
if
-rakenteen sisällä oleva koodi suoritetaan, jos ehdon totuusarvo
on true
eli muuttujan arvo on true
.
Tällä hetkellä saattaa tuntua vaikealta keksiä käyttöä totuusarvomuuttujalle, koska esimerkiksi yllä olevan koodin voisi kirjoittaa lyhyemmin ilman muuttujaa. Myöhemmin kuitenkin huomaamme, että totuusarvomuuttuja voi olla varsin hyödyllinen.
Ikuinen silmukka on silmukka, jonka toistamista ei ole rajoitettu. Javassa ikuinen silmukka voidaan luoda seuraavasti:
while (true) { [koodi] }
Tämä silmukka jatkuu niin kauan, kuin ehto true
on tosi –
mutta tämä ehto on aina tosi. Ongelmaksi näyttää siis tulevan, että silmukka
ei pääty milloinkaan.
Silmukan lopettamiseen on kuitenkin myös toinen tapa: komento
break
. Tämä komento silmukan sisällä lopettaa silmukan
välittömästi riippumatta silmukan ehdosta.
Tyypillinen ikuinen silmukka näyttää seuraavalta:
while (true) { ... if ([ehto]) { break; } ... }
Seuraavat esimerkit näyttävät, mitä hyötyä ikuisesta silmukasta voi olla.
Seuraava ohjelma kysyy käyttäjältä salasanaa, kunnes käyttäjä antaa oikean salasanan.
while (true) { System.out.print("Anna salasana: "); String salasana = input.nextLine(); if (salasana.equals("kissa")) { break; } System.out.println("Väärin meni!"); } System.out.println("Tervetuloa!");
Ohjelman suoritus voi olla seuraava:
Anna salasana: koira Väärin meni! Anna salasana: lehmä Väärin meni! Anna salasana: kissa Tervetuloa!
Seuraava ohjelma kysyy käyttäjältä ikää, kunnes käyttäjä antaa kelvollisen iän:
while (true) { System.out.print("Kuinka vanha olet? "); int ika = Integer.parseInt(input.nextLine()); if (ika >= 0 && ika <= 120) { break; } System.out.println("Ikä ei kelpaa!"); } System.out.println("Kiitos!");
Ohjelman suoritus voi olla seuraava:
Kuinka vanha olet? -5 Ikä ei kelpaa! Kuinka vanha olet? 139 Ikä ei kelpaa! Kuinka vanha olet? 56 Kiitos!
Tässä silmukan lopettamisen ehtona on, että ikä on välillä 0–120.
Silmukan muodostamiseen on yleensäkin kaksi eri tapaa:
true
ja silmukassa on sopivassa
kohdassa break
.
Seuraavat koodit havainnollistavat asiaa:
ehto rungossa | käytössä break |
---|---|
String salasana = ""; while (!salasana.equals("kissa")) { System.out.print("Anna salasana: "); salasana = input.nextLine(); } |
while (true) { System.out.print("Anna salasana: "); String salasana = input.nextLine(); if (salasana.equals("kissa")) { break; } } |
Molemmat koodit toimivat, ja on makuasia, kumpaa haluaa käyttää. Koodien ajattelutapa on kuitenkin erilainen: vasemmassa koodissa ajatellaan "silmukka jatkuu niin kauan, kuin salasana ei ole kissa" kun taas oikeassa koodissa ajatellaan "silmukka jatkuu, kunnes salasana on kissa".
Seuraava asia on hyvä tiedostaa: Jos muuttujan määrittelee silmukan sisällä, sen alkuarvo palautetaan silmukan jokaisella kierroksella eikä muuttujaa voi käyttää muualla kuin silmukan sisällä.
Esimerkiksi seuraava koodi ei toimi:
while (summa < 100) { int summa = 0; summa = summa + 1; }
Nyt muuttuja summa
nollautuu silmukan joka kierroksella eikä
siihen voi edes viitata silmukan ehdossa.
Mistä tietää, kannattaako toistaminen tehdä for-silmukan vai while-silmukan avulla?
Perussääntö on, että jos toistokertojen määrä on tiedossa ennen silmukan aloittamista (esim. koodi toistetaan 5 kertaa), for-silmukka on luonteva valinta, ja muussa tapauksessa while-silmukka sopii ehkä paremmin.
Kuitenkin kummalla tahansa silmukalla voi toteuttaa minkä tahansa toistorakenteen. Niinpä toinen silmukka on tavallaan "turha". Molemmat silmukat ovat Javassa, koska molemmille on luontevia käyttötilanteita.
Hauska lisätehtävä: Mieti, miten voit korvata for-silmukan while-silmukalla ja päinvastoin.