Ehtolauseet ja vaihtoehtoinen toiminta
Ohjelmamme ovat tähän mennessä olleet lineaarisia eli ohjelmien suoritus on tapahtunut ylhäältä alaspäin ilman suuria yllätyksiä tai vaihtoehtoja. Ohjelmiin halutaan kuitenkin usein vaihtoehtoista toiminnallisuutta, eli toiminnallisuutta joka riippuu tavalla tai toisella ohjelmassa olevien muuttujien tilasta.
Jotta ohjelman suoritus voisi haarautua esimerkiksi käyttäjän antaman syötteen perusteella, tarvitsemme käyttöömme ehtolauseen. Yksinkertaisin ehtolause on seuraavanlainen.
System.out.println("Hei maailma!");
if (true) {
System.out.println("Et voi välttää tätä koodia!");
}
Hei maailma! Et voi välttää tätä koodia!
Ehtolause alkaa avainsanalla if
, jota seuraa sulut. Sulkujen sisälle asetetaan lauseke, joka evaluoidaan kun ehtolause saavutetaan. Evaluoinnin tulos on totuusarvo, yllä evaluointia ei tehty, vaan ehtolauseessa käytettiin suoraan totuusarvoa.
Sulkuja seuraa lohko, joka määritellään avaavan aaltosulun {
ja sulkevan aaltosulun }
sisään. Lohkon sisällä oleva lähdekoodi mikäli sulkujen sisälle asetettu lauseke evaluoidaan todeksi (true).
Tarkastellaan esimerkkiä, missä ehtolauseen lausekkeessa vertaillaan lukuja.
int luku = 11;
if (luku > 10) {
System.out.println("Luku oli suurempi kuin 10");
}
Jos ehtolauseen lauseke evaluoidaan todeksi, yllä "jos muuttujassa luku oleva arvo on suurempi kuin 10", ohjelman suoritus siirtyy ehtolauseen määrittelemään lohkoon. Jos taas lauseke on epätotta, ohjelman suoritus siirtyy ehtolauseeseen liittyvän lohkon päättävän aaltosulun jälkeiseen lauseeseen.
Huomaa, että if
-lauseen perään ei tule puolipistettä, sillä lause ei lopu ehto-osan jälkeen.
Vertailuoperaattorit
Vertailuoperaattoreita ovat seuraavat:
>
suurempi kuin>=
suurempi tai yhtä suuri kuin<
pienempi kuin<=
pienempi tai yhtä suuri kuin==
yhtä suuri kuin!=
erisuuri kuin
int luku = 55;
if (luku != 0) {
System.out.println("Luku oli erisuuri kuin 0");
}
if (luku >= 1000) {
System.out.println("Luku oli vähintään 1000");
}
Luku oli erisuuri kuin 0
Muulloin eli else
Jos ehtolauseen sulkujen sisällä oleva lauseke evaluoituu epätodeksi, ohjelmakoodin suoritus siirtyy ehtolauseen lohkon lopettavan aaltosulun seuraavaan lauseeseen. Tämä ei aina ole toivottua, vaan usein halutaan luoda vaihtoehtoinen toiminta tilanteeseen, missä ehtolauseen lauseke on epätotta.
Tämä onnistuu if
-komennon yhteydessä käytettävän else
-komennon avulla.
int luku = 4;
if (luku > 5) {
System.out.println("Lukusi on suurempi kuin viisi!");
} else {
System.out.println("Lukusi on viisi tai alle!");
}
Lukusi on viisi tai alle!
Jos ehtolauseeseen on määritelty else
-haara, suoritetaan else-haaran määrittelemä lohko jos ehtolauseen ehto ei ole totta. Komento else
tulee samalle riville if
-komennon määrittelemän lohkon lopettavan aaltosulun kanssa.
Lisää vaihtoehtoja: else if
Jos vaihtoehtoja on useampia käytetään else if
-komentoa. Komento else if
on kuin else
, mutta lisäehdolla. else if
tulee if
-ehdon jälkeen, ja niitä voi olla useita.
int luku = 3;
if (luku == 1) {
System.out.println("Luku on yksi");
} else if (luku == 2) {
System.out.println("Lukuna on kaksi");
} else if (luku == 3) {
System.out.println("Kolme lienee lukuna!");
} else {
System.out.println("Jotain muuta!");
}
Kolme lienee lukuna!
Luetaan yllä oleva esimerkki: 'Jos luku on yksi, tulosta "Luku on yksi", muuten jos luku on kaksi, tulosta "Lukuna on kaksi", muuten jos lukuna on kolme, tulosta "Kolme lienee lukuna!". Muulloin, tulosta "Jotain muuta!"'.
Yllä olevan ohjelman askeleittainen visualisointi:
Vertailujen suoritusjärjestys
Vertailut suoritetaan järjestyksessä ylhäältä alaspäin. Kun suorituksessa päästään ehtolauseeseen, jonka ehto on totta, suoritetaan lohko ja lopetetaan vertailu.
int luku = 5;
if (luku == 0) {
System.out.println("Luku on nolla.");
} else if (luku > 0) {
System.out.println("Luku on suurempi kuin nolla.");
} else if (luku > 2) {
System.out.println("Luku on suurempi kuin kaksi.");
} else {
System.out.println("Luku on pienempi kuin nolla.");
}
Luku on suurempi kuin nolla.
Yllä oleva esimerkki tulostaa merkkijonon "Luku on suurempi kuin nolla." vaikka myös ehto luku > 2
on totta. Vertailu lopetetaan ensimmäiseen valintakäskyyn, jonka ehto on totta.
Ehtolauseen lauseke ja totuusarvomuuttuja
Ehtolauseen sulkuihin asetettavan arvon tulee olla lausekkeen evaluoinnin jälkeen totuusarvotyyppinen. Totuusarvomuuttujan tyyppi on boolean
ja arvo true tai false.
boolean onkoTotta = true;
System.out.println("Totuusarvomuuttujan arvo on " + onkoTotta);
Totuusarvomuuttujan arvo on true
Ehtolauseen voi suorittaa myös seuraavasti:
boolean onkoTotta = true;
if (onkoTotta) {
System.out.println("Aika vinhaa!");
}
Aika vinhaa!
Vertailuoperaattoreita voi käyttää myös ehtojen ulkopuolella. Tällöin vertailun tuloksena saatu totuusarvo asetetaan talteen totuusarvomuuttujaan myöhempää käyttöä varten.
int eka = 1;
int toka = 3;
boolean onkoSuurempi = eka > toka;
Yllä olevassa esimerkissä totuusarvomuuttuja onkoSuurempi
sisältää nyt totuusarvon false. Yllä olevaa esimerkkiä voi myös jatkaa ja ottaa siihen mukaan ehtolauseen.
int eka = 1;
int toka = 3;
boolean onkoPienempi = eka < toka;
if (onkoPienempi) {
System.out.println("1 on pienempi kuin 3!");
}
Yllä olevassa kuvassa ohjelmakoodia on suoritettu niin pitkään, että ohjelman muuttujat on luotu ja niihin on asetettu arvot. Muuttujassa onkoPienempi
on arvona true
. Seuraavana suoritetaan vertailu if (onkoPienempi)
— muuttujaan onkoPienempi
liittyvä arvo löytyy sen lokerosta, ja lopulta ohjelma tulostaa:
1 on pienempi kuin 3!
Ehtolauseet ja merkkijonojen vertailu
Siinä missä kokonaislukujen, liukulukujen, ja totuusarvojen samuutta voi verrata kahdella yhtäsuuruusmerkillä (muuttuja1 == muuttuja2
), ei merkkijonojen samuuden vertailu kahdella yhtäsuuruusmerkillä onnistu.
Voit kokeilla tätä seuraavalla ohjelmalla:
Scanner lukija = new Scanner(System.in);
System.out.println("Syötä ensimmäinen merkkijono");
String eka = lukija.nextLine();
System.out.println("Syötä toinen merkkijono");
String toka = lukija.nextLine();
if (eka == toka) {
System.out.println("Merkkijonot olivat samat!");
} else {
System.out.println("Merkkijonot olivat eri!");
}
Syötä ensimmäinen merkkijono sama Syötä toinen merkkijono sama Merkkijonot olivat eri!
Syötä ensimmäinen merkkijono sama Syötä toinen merkkijono eri Merkkijonot olivat eri!
Tämä liittyy merkkijonojen sisäiseen toimintaan sekä siihen, miten muuttujien vertailu on Javassa toteutettu. Käytännössä vertailun toimintaan vaikuttaa se, kuinka paljon tietoa muuttuja voi sisältää — merkkijonot voivat sisältää äärettömän määrän merkkejä, kun taas kokonaisluvut, liukuluvut ja totuusarvot sisältävät aina yhden luvun tai arvon. Muuttujia, jotka sisältävät aina vain yhden luvun tai arvon voi verrata yhtäsuuruusmerkillä, kun taas enemmän tietoa sisältävillä muuttujille tällainen vertailu ei toimi. Palaamme tähän tarkemmin myöhemmin tällä kurssilla.
Merkkijonojen vertailussa käytetään merkkijonomuuttujiin liittyvää equals
-komentoa. Komento toimii seuraavalla tavalla:
Scanner lukija = new Scanner(System.in);
System.out.println("Syötä merkkijono");
String syote = lukija.nextLine();
if (syote.equals("merkkijono")) {
System.out.println("Luit ohjeet oikein, hyvä!");
} else {
System.out.println("Metsään meni!");
}
Syötä merkkijono ok! Metsään meni!
Syötä merkkijono merkkijono Luit ohjeet oikein, hyvä!
Komento equals kirjoitetaan merkkijonomuuttujan jälkeen siten, että se kiinnitetään pisteellä vertailtavaan muuttujaan. Komennolle annetaan parametrina merkkijono, johon muuttujaa vertaillaan. Mikäli merkkijonomuuttujaa vertaillaan suoraan merkkijonoon, voi merkkijonon asettaa hipsuilla merkittynä equals-komennon sulkujen sisään. Muulloin sulkujen sisään asetetaan sen merkkijonomuuttujan nimi, johon merkkijonomuuttujan sisältämää merkkijonoa verrataan.
Alla olevassa esimerkissä luetaan käyttäjältä kaksi merkkijonoa. Ensin tarkastetaan ovatko syötetyt merkkijonot samat, jonka jälkeen tarkastetaan onko syötettyjen merkkijonojen arvo "kaksi merkkijonoa".
Scanner lukija = new Scanner(System.in);
System.out.println("Syötä kaksi merkkijonoa");
String eka = lukija.nextLine();
String toka = lukija.nextLine();
if (eka.equals(toka)) {
System.out.println("Merkkijonot olivat samat!");
} else {
System.out.println("Merkkijonot olivat eri!");
}
if (eka.equals("kaksi merkkijonoa")) {
System.out.println("Nokkelaa!");
}
if (toka.equals("kaksi merkkijonoa")) {
System.out.println("Ovelaa!");
}
Syötä kaksi merkkijonoa hei maailma Merkkijonot olivat eri!
Syötä kaksi merkkijonoa kaksi merkkijonoa maailma Merkkijonot olivat eri! Nokkelaa!
Syötä kaksi merkkijonoa samat samat Merkkijonot olivat samat!
Muistathan tarkistaa pistetilanteesi materiaalin oikeassa alareunassa olevasta pallosta!