1. Ohjelmoinnin perusteet, kesä Aloittaminen Tulostaminen Muuttujat if-rakenne Metodit

Koko: px
Aloita esitys sivulta:

Download "1. Ohjelmoinnin perusteet, kesä 2012... 2 1.1 Aloittaminen... 2 1.2 Tulostaminen... 6 1.3 Muuttujat... 8 1.4 if-rakenne... 12 1.5 Metodit... 15 1."

Transkriptio

1 1. Ohjelmoinnin perusteet, kesä Aloittaminen Tulostaminen Muuttujat if-rakenne Metodit Tehtävät for-silmukka Merkkijonot Matematiikka Tehtävät while-silmukka Taulukko Olio-ohjelmointi Algoritmit Tehtävät Cheatsheet

2 Ohjelmoinnin perusteet, kesä 2012 Tälle sivustolle on koottu kesän 2012 Ohjelmoinnin perusteiden materiaali ja tehtävät. Otamme mielellään vastaan palautetta materiaalista ja tehtävistä. Voit lähettää virheilmoituksia ja parannusehdotuksia tänne: Osa 1 Osan 1 tehtävien deadline on ti klo 23:59. Aloittaminen Tulostaminen Muuttujat if-rakenne Metodit Tehtävät Osa 2 Osan 2 tehtävien deadline on ti klo 23:59. for-silmukka while-silmukka Merkkijonot Matematiikka Tehtävät Osa 3 Osan 3 tehtävien deadline on ti 5.6. klo 23:59. while-silmukka Taulukko Olio-ohjelmointi Algoritmit Tehtävät Lisäksi: Cheatsheet Aloittaminen NetBeansin asennus Kurssilla käytetään NetBeans-ohjelmaa, joka on monipuolinen Java-ohjelmointiympäristö. NetBeans on asennettuna valmiiksi tietojenkäsittelytieteen laitoksen Linux-ympäristöön. Saat käynnistettyä NetBeansin valitsemalla ylävalikosta Applications kohta Programming ja edelleen kohta NetBeans IDE. Voit myös asentaa ohjelman omalle koneellesi seuraavasti: Mene sivulle Paina napista "Download" kohdan "Java SE" alapuolelta. Käynnistä asennusohjelma ja seuraa sen ohjeita. Ensimmäinen ohjelma Ohjelman koodi on tietokoneelle annettava tekstimuotoinen kuvaus ohjelman toiminnasta. Tietokone suorittaa ohjelman toteuttamalla koodissa olevat komennot. Seuraavassa on ensimmäisen Java-ohjelmamme koodi:

3 import java.util.*; public class EkaOhjelma { private static Scanner input = new Scanner(System.in); public static void main(string[] args) { System.out.println("Ohjelmointi alkaa..."); System.out.print("Mikä on nimesi? "); String nimi = input.nextline(); System.out.println("Hei vain, " + nimi + "!"); Ohjelman tarkoituksena on toimia seuraavasti: Ohjelma näyttää tekstin "Ohjelmointi alkaa..." Ohjelma näyttää tekstin "Mikä on nimesi?" Ohjelma kysyy käyttäjältä nimen. Ohjelma näyttää tekstin "Hei vain, X!", jossa X on käyttäjän nimi. Tässä vaiheessa ei ole tärkeää ymmärtää kaikkea ohjelman koodissa, vaan siinä esiintyvät asiat tulevat tutuksi kurssin aikana. NetBeansin käyttäminen Kokeillaan seuraavaksi kirjoittaa ja suorittaa ohjelma NetBeans-ympäristössä. Valitse File -> New Project uuden ohjelman aloittamiseksi. Esiin tulee seuraava ikkuna, josta riittää painaa Next: Kirjoita sitten kohtiin Project Name ja Create Main Class ohjelman nimi (tässä tapauksessa EkaOhjelma) ja paina Finish. Nyt avautuu tekstieditori, johon voit kirjoittaa ohjelman koodin. Editorissa on valmiina ohjelman pohja, jonka voit korvata tämän sivun alussa olevalla koodilla. Ohjelman pitäisi näyttää nyt tältä:

4 Kun painat Shift + F6, ohjelman suoritus alkaa. Ohjelmaan liittyvät tekstit ilmestyvät ikkunan alalaitaan. Tänne voit myös kirjoittaa nimesi, jota ohjelma kysyy. Suorituksen pitäisi näyttää tältä: TMC-järjestelmä Kurssilla käytetään TMC-järjestelmää, jonka kautta saat automaattisesti kurssin tehtävät NetBeansiin sekä pystyt palauttamaan vastaukset niihin. Saat tunnuksen TMC-järjestelmään seuraavasti: Mene sivulle Kirjoita kohtaan Username haluamasi käyttäjätunnus ja kohtiin First name ja Last name oikea nimesi. Käyttäjätunnus tulee näkymään kurssin tuloslistoissa. Täytä lomake loppuun ja lähetä tiedot. Tämän jälkeen asenna TMC-lisäosa NetBeansiin seuraavasti: Valitse valikosta Tools alakohta Plugins. Valitse avautuvasta ikkunasta välilehti Settings ja paina nappia Add. Kirjoita kohtaan Name nimi TMC ja kohtaan URL seuraava osoite: Paina nappia ja odota hetki. Siirry välilehteen Available Plugins ja kirjoita kohtaan Search hakusana TMC.

5 6. Rastita valinta Install listassa ja paina nappia Install. 7. Seuraa asennusohjeita. Jos NetBeans varoittaa, että lisäosa ei ole "signed", paina Continue. 8. Asennuksen jälkeen NetBeans käynnistää itsensä uudestaan automaattisesti. Kun NetBeans käynnistyy uudestaan, esiin tulee ikkuna TMC Settings. Pääset tähän ikkunaan uudestaan valitsemalla valikosta TMC kohta Settings. Kirjoita ikkunaan valitsemasi käyttäjänimi ja salasana. Paina vielä nappia Refresh list ja valitse kurssi avoin-ohpe Kun painat OK, NetBeans lataa kurssin tehtävät vasempaan listaan. Tehtävän ratkaiseminen Ratkaistaan vielä testiksi viikon 1 ensimmäinen tehtävä, "Ensimmäinen ohjelma". Tehtävän ratkaisuun riittää yksi rivi koodia. Tämän jälkeen voit suorittaa ohjelman painamalla Shift + F6: Jokaiseen kurssin tehtävään liittyy testejä, jotka pyrkivät varmistamaan, että ohjelmasi toimii oikein. Voit suorittaa tehtävän testit NetBeansissa painamalla yläriviltä toiseksi viimeistä nappia, jossa on silmä. Jos ohjelmassa on virhe, testi yleensä huomaa sen. Esimerkiksi jos ohjelma tulostaa "Heiparallaa" eikä "Heipparallaa", käy näin: Jos kaikki testit menevät läpi, NetBeans ehdottaa koodin lähettämistä palvelimelle. Palvelin varmistaa vielä, että testit menevät läpi, minkä jälkeen saat automaattisesti pisteen kyseisestä tehtävästä. Voit myös katsoa tehtävän malliratkaisun sekä antaa palautetta tehtävästä. Tehtävien pisteet ilmestyvät tarkistuslistaan seuraavalle sivulle:

6 Tulostaminen Ohjelman runko Kurssin alkuvaiheessa ohjelmamme runko on aina seuraava: public class OhjelmanNimi { public static void main(string[] args) {... Kolmen pisteen kohdalle tulee ohjelman varsinainen sisältö, ja rungon alkuosa ja loppuosa toistuvat aina muuttumattomina. Niiden merkitykseen palataan myöhemmin. Tulostaminen Tulostaminen tarkoittaa, että ohjelma näyttää tekstiä ruudulla. Javan tulostuskomennot ovat seuraavat: System.out.println tulostaa tekstin ja rivinvaihdon. System.out.print tulostaa tekstin ilman rivinvaihtoa. Esimerkki Tarkastellaan seuraavaa ohjelmaa: System.out.println("Ensimmäinen rivi"); System.out.println("Toinen rivi"); System.out.println("Kolmas rivi"); Ohjelma tulostaa seuraavat kolme riviä: Ensimmäinen rivi Toinen rivi Kolmas rivi Kokeile, että saat ohjelman suoritettua NetBeansissa. Ohjelman nimeksi sopii vaikkapa Tulostaminen. Ohjelman ympärille tulee sivun yläosassa oleva runko, ja tämä käytäntö jatkuu tulevissa esimerkeissä. Havaintoja Ohjelmasta voidaan havaita seuraavat Java-kielen asiat: Ohjelman suoritus etenee rivi kerrallaan ylhäältä alas. Jokaisen komennon loppuun tulee puolipiste (;). Ohjelmassa oleva teksti tulee lainausmerkkien (") sisään. Rivinvaihdot Komento System.out.print ei lisää tekstin loppuun rivinvaihtoa. Tätä havainnollistaa seuraava ohjelma: System.out.print("Nämä "); System.out.print("sanat "); System.out.print("tulevat "); System.out.print("samalle "); System.out.println("riville."); Ohjelman tulostus on seuraava:

7 Nämä sanat tulevat samalle riville. Tässä viimeinen komento on kuitenkin System.out.println, jotta viimeisen sanan jälkeen tulee rivinvaihto. Erikoismerkinnät Seuraavilla merkinnöillä on erikoismerkitys: \n tarkoittaa rivinvaihtoa. \" tarkoittaa merkkiä ". \\ tarkoittaa merkkiä \. Seuraava ohjelma esittelee erikoismerkintöjä: System.out.print("Ensimmäinen rivi\ntoinen rivi\nkolmas rivi\n"); System.out.println("System.out.println(\"abc\");"); Ohjelman tulostus on seuraava: Ensimmäinen rivi Toinen rivi Kolmas rivi System.out.println("abc"); Luvut ja laskut Tekstin sijasta voidaan tulostaa myös lukuja ja laskujen tuloksia: System.out.println(12); System.out.println( ); System.out.println(12345 * 54321); Ohjelman tulostus on seuraava: Tekstiä ja lukuarvoja voi myös yhdistää +-merkillä: System.out.println("Summa:" + ( )); System.out.println("Vuorokaudessa on " + (60 * 60 * 24) + " sekuntia."); Ohjelman tulostus on seuraava: Summa: 15 Vuorokaudessa on sekuntia Kommentti Kommentti on koodissa oleva huomautus, joka ei vaikuta ohjelman toimintaan. Kommentin avulla koodin toimintaa voi selventää koodin lukijalle. Kuitenkin kannattaa pyrkiä siihen, että koodi on muutenkin niin selvää, että kommentteja ei juuri tarvitse. Kommentin saa kirjoittamalla riville //, jolloin rivin loppuosasta tulee kommentti. Kommentti voi näyttää seuraavalta: // vuorokauden sekuntien määrä System.out.println(60 * 60 * 24);

8 Pidemmän kommentin saa tehtyä kirjoittamalla sen merkkien /* ja */ väliin: /* minuutissa on 60 sekuntia, tunnissa on 60 minuuttia ja vuorokaudessa on 24 tuntia */ System.out.println(60 * 60 * 24); NetBeans-vinkki Komentoa System.out.println tarvitsee hyvin usein. Voit kirjoittaa komennon nopeasti NetBeansissa kirjoittamalla sout ja painamalla Tab-näppäintä. Muuttujat Muuttuja Muuttuja on muistipaikka, jossa ohjelma voi säilyttää tarvitsemaansa tietoa. Muuttujan nimi on tunnus, jolla siihen viitataan ohjelmassa. Muuttujan nimessä voi olla kirjaimia (a...z ja A...Z) sekä numeroita (0...9), mutta nimi ei saa alkaa numerolla. Muuttujan tyyppi tarkoittaa, millaista tietoa muuttujaan voi tallentaa. Javan tärkeimmät muuttujatyypit ovat seuraavat: String: merkkijono eli tekstiä (esim. "Aapeli") int: kokonaisluku (esim. 123) double: desimaaliluku (esim ) char: yksi merkki (esim. 'A') boolean: totuusarvo (true tai false) Muuttujan arvo tarkoittaa muuttujan sisältöä tietyllä ohjelman suorituksen hetkellä. Nimensä mukaisesti muuttujan arvo voi muuttua. Esimerkki Seuraavassa esimerkissä määritellään muuttujat nimi ja ika. Muuttujien arvoiksi laitetaan "Aapeli" ja 31, minkä jälkeen arvot tulostetaan. String nimi = "Aapeli"; int ika = 31; System.out.println(nimi + " on " + ika + " vuotta vanha."); Ohjelman tulostus on seuraava: Aapeli on 31 vuotta vanha. Määrittely Muuttuja täytyy aina määritellä, ennen kuin sitä voi alkaa käyttää. Määrittelyssä ilmoitetaan muuttujan tyyppi, nimi ja aloitusarvo. Määrittelyn kirjoitustapa on seuraava: [tyyppi] [nimi] = [aloitusarvo]; Määrittelyn jälkeen muuttujaan voi viitata sille annetulla nimellä. Muuttujan nimi on ohjelmoijan päätettävissä, mutta nimi kannattaa valita kuvaavaksi, jotta siitä näkee muuttujan käyttötarkoituksen. Muuttaminen Muuttujan arvoa voi muuttaa seuraavasti: [nimi] = [uusi arvo]; Muuttujan uuden arvon muodostuksessa voi käyttää sen vanhaa arvoa sekä muiden muuttujien arvoja. Tarkastellaan seuraavaa ohjelmaa:

9 int a = 3; int b = 1; int c = 8; a = 4; b = b + 1; c = c - 2; b = 5; b = a + b; c = a * b; a = 2 * b - 3; System.out.println(a + " " + b + " " + c); Ohjelman tulostus on seuraava: Ohjelmassa tapahtuu seuraavaa: koodi selitys lopputulos int a = 3; int b = 1; int c = 8; muuttujien määrittely a = 3, b = 1, c = 8 a = 4; a saa arvon 4 a = 4, b = 1, c = 8 b = b + 1; b:n arvo kasvaa 1:llä a = 4, b = 2, c = 8 c = c - 2; c:n arvo vähenee 2:lla a = 4, b = 2, c = 6 b = 5; b saa arvon 5 a = 4, b = 5, c = 6 b = a + b; b saa arvokseen a:n ja b:n summan a = 4, b = 9, c = 6 c = a * b; c saa arvokseen a:n ja b:n tulon a = 4, b = 9, c = 36 a = 2 * b - 3; a saa arvokseen 2 * b - 3 a = 15, b = 9, c = 36 Äskeisen esimerkin ymmärtäminen on tärkeää. Älä mene eteenpäin, ennen kuin olet ymmärtänyt kokonaan, mitä ohjelmassa tapahtuu. Lyhennysmerkintöjä Tietyt muuttujien muutokset ovat hyvin tavallisia. Javassa ovat käytössä mm. seuraavat lyhennysmerkinnät: koodi a = a + 1 a = a - 1 a = a + b a = a - b lyhennys a++ a-- a += b a -= b Seuraavat kaksi ohjelmaa toimivat samoin: koodi lyhennys int a = 2; a = a + 1; System.out.println(a); a = a + 3; System.out.println(a); int a = 2; a++; System.out.println(a); a += 3; System.out.println(a); Arvo käyttäjältä Tyypillinen tapa saada muuttujalle arvo on lukea se käyttäjältä. Jos ohjelma lukee tietoa käyttäjältä, ohjelman runkoa täytyy muuttaa

10 seuraavasti: import java.util.*; public class OhjelmanNimi { public static Scanner input = new Scanner(System.in); public static void main(string[] args) {... Tämän jälkeen ohjelma pystyy lukemaan merkkijonon käyttäjältä seuraavasti: String merkkijono = input.nextline(); Kokonaislukujen ja desimaalilukujen lukeminen on hieman vaikeampaa, koska ne pitää muuttaa merkkijonosta lukuarvoiksi. Tämä onnistuu seuraavasti: int kokonaisluku = Integer.parseInt(input.nextLine()); double desimaaliluku = Double.parseDouble(input.nextLine()); Seuraava ohjelma kysyy käyttäjän nimen ja iän. Sitten ohjelma tulostaa ne uudestaan. System.out.print("Mikä on nimesi? "); String nimi = input.nextline(); System.out.print("Kuinka vanha olet? "); int ika = Integer.parseInt(input.nextLine()); System.out.println("Nimesi on " + nimi + " ja olet " + ika + " vuotta vanha."); Ohjelman tulostus voi olla seuraava: Mikä on nimesi? Aapeli Kuinka vanha olet? 31 Nimesi on Aapeli ja olet 31 vuotta vanha. Esimerkki: Tarina Seuraava ohjelma kysyy käyttäjän nimen ja tulostaa tarinan, jonka päähenkilönä käyttäjä on. System.out.print("Anna nimesi: "); String nimi = input.nextline(); System.out.println(); System.out.println("Syrjäisessä laaksossa asui " + nimi + ","); System.out.println("joka oli ammatiltaan lammaspaimen."); System.out.println(nimi + " oli vasta herännyt,"); System.out.println("kun pihaan ratsasti tumma-asuinen ritari."); System.out.println("Pian " + nimi + " saisi kuulla, että hänet oli"); System.out.println("valittu tärkeään tehtävään..."); Ohjelman tulostus voi olla seuraava: Anna nimesi: Aapeli Syrjäisessä laaksossa asui Aapeli, joka oli ammatiltaan lammaspaimen. Aapeli oli vasta herännyt, kun pihaan ratsasti tumma-asuinen ritari. Pian Aapeli saisi kuulla, että hänet oli valittu tärkeään tehtävään... Tai myös seuraava:

11 Anna nimesi: Maija Syrjäisessä laaksossa asui Maija, joka oli ammatiltaan lammaspaimen. Maija oli vasta herännyt, kun pihaan ratsasti tumma-asuinen ritari. Pian Maija saisi kuulla, että hänet oli valittu tärkeään tehtävään... Huomaa komento System.out.println ilman tulostettavaa tekstiä: se saa aikaan tyhjän rivin. Muuttujan tyypin valinta Mistä tietää, mikä tyyppi on sopiva muuttujalle? Esimerkiksi luvun 12 voi tallentaa merkkijonona, kokonaislukuna ja desimaalilukuna: String a = "12"; int b = 12; double c = 12.0; Muuttujan tyyppi kannattaa valita muuttujan käyttötarkoituksen mukaan. Jos muuttujalla on tarkoitus laskea, lukuarvotyypit ovat luonteva valinta. Jos taas muuttujaa käsitellään tekstin tavoin, sen kannattaa olla merkkijono. Lukuarvot kannattaa yleensä tallentaa int-tyyppisinä. Vain jos lukuarvoissa tarvitaan desimaaliosaa, double-tyyppi on perusteltu. Jakolasku Yhteenlasku, vähennyslasku ja kertolasku toimivat Javassa luonnollisella tavalla, mutta jakolasku saattaa tuottaa yllätyksiä. Jos jakolaskun molemmat luvut ovat kokonaislukuja, myös tulos on kokonaisluku, vaikka todellisuudessa jako ei menisi tasan. Jos taas ainakin toinen luvuista on desimaaliluku, tulos on desimaaliluku. Seuraavan koodin toiminta voi yllättää: int luku1 = 3; int luku2 = 5; double tulos = luku1 / luku2; System.out.println(tulos); Koodin tulostus on seuraava: 0.0 Vaikka muuttujan tulos tyyppi on double, tuloksen desimaaliosa on kadonnut. Ratkaisu ongelmaan on muuttaa toinen jakolaskussa olevista luvuista desimaaliluvuksi. Tämän voi tehdä vaikkapa seuraavasti: double tulos = (double)luku1 / luku2; Nyt koodin tulostus on haluttu: 0.6 Javan nimeämiskäytäntö Java-kielessä muuttujat nimetään tavallisesti niin, että muuttujan nimi alkaa pienellä, mutta jos nimessä on monta sanaa, kaikki seuraavat sanat alkavat suurella. Tähän käytäntöön ei ole mitään syvällistä syytä, mutta se on järkevää omaksua, koska käytännöstä poikkeava koodi näyttää oudolta kokeneen Java-ohjelmoijan silmissä. Seuraavat muuttujanimet vastaavat käytäntöä: pelaajannimi pistemaara

12 toiseksisuurinluku if-rakenne if-rakenne if-rakenteen avulla ohjelman toiminnan saa riippumaan muuttujien arvoista. Rakenteen tavallisimmat muodot ovat seuraavat: Muoto 1: if ([ehto]) { [koodi] Tässä ohjelma suorittaa kohdassa [koodi] olevan koodin, jos [ehto] pitää paikkansa. Muoto 2: if ([ehto]) { [koodi1] else { [koodi2] Tässä ohjelma suorittaa kohdassa [koodi1] olevan koodin, jos [ehto] pitää paikkansa, ja muussa tapauksessa kohdassa [koodi2] olevan koodin. Esimerkki: Salasana Seuraava ohjelma kysyy käyttäjältä salasanan. Sitten ohjelma kertoo, oliko salasana oikein. Tässä oikea salasana on "kissa". System.out.print("Anna salasana: "); String salasana = input.nextline(); if (salasana.equals("kissa")) { System.out.println("Oikein meni!"); else { System.out.println("Väärin meni!"); Esimerkkejä ohjelman suorituksesta: Anna salasana: kissa Oikein meni! Anna salasana: koira Väärin meni! Esimerkki: Pituus Seuraava ohjelma varmistaa, että muuttujalle pituus ei tule negatiivista arvoa. Jos pituus on alle 0, ohjelma muuttaa sen arvoksi 0. System.out.print("Anna pituus: "); int pituus = Integer.parseInt(input.nextLine()); if (pituus < 0) { pituus = 0; System.out.println("Pituus: " + pituus); Esimerkkejä ohjelman suorituksesta:

13 Anna pituus: 5 Pituus: 5 Anna pituus: -2 Pituus: 0 Ehdot if-rakenteessa oleva ehto liittyy yleensä muuttujien arvoon. Äskeisissä esimerkeissä ehdot olivat "muuttujan salasana arvo on kissa" ja "muuttujan pituus arvo on alle 0". Merkkijonoista halutaan yleensä tarkistaa, ovatko ne samat. Tämä onnistuu equals-komennolla esimerkin mukaisesti. Lukuarvoista halutaan yleensä tarkistaa niiden suuruusjärjestys. Käytössä ovat merkinnät == (luvut ovat samat),!= (luvut eivät ole samat), < (vasen luku on pienempi), > (vasen luku on suurempi) <= (vasen luku on sama tai pienempi) ja >= (vasen luku on sama tai suurempi). Monta ehtoa Ehtoja voidaan yhdistää seuraavilla merkinnöillä: [ehto1] && [ehto2] vaatimus: molemmat ehdot pätevät [ehto1] [ehto2] vaatimus: jompikumpi tai molemmat ehdot pätevät Lisäksi ehdon voi muuttaa käänteiseksi seuraavasti:![ehto] vaatimus: ehto ei saa päteä Esimerkki: Tunnus ja salasana Seuraava ohjelma vaatii, että käyttäjä antaa oikean tunnuksen (aapeli) ja oikean salasanan (kissa). System.out.print("Anna tunnus: "); String tunnus = input.nextline(); System.out.print("Anna salasana: "); String salasana = input.nextline(); if (tunnus.equals("aapeli") && salasana.equals("kissa")) { System.out.println("Oikein meni!"); System.out.println("Tervetuloa järjestelmään..."); else { System.out.println("Väärin meni!"); System.out.println("Yritä vielä uudestaan..."); Esimerkkejä ohjelman suorituksesta: Anna tunnus: aapeli Anna salasana: kissa Oikein meni! Tervetuloa järjestelmään... Anna tunnus: aapeli Anna salasana: koira Väärin meni! Yritä vielä uudestaan...

14 Anna tunnus: maija Anna salasana: koira Väärin meni! Yritä vielä uudestaan... Pitkä if-rakenne if-rakenteesta on myös olemassa pitkä muoto, jossa voi olla monia ehtoja. Muoto 3: if ([ehto]) { [koodi] else if ([ehto]) { [koodi] else if ([ehto]) { [koodi]... else { [koodi] Tässä ohjelma valitsee ensimmäisen ehdon, joka pitää paikkansa, ja suorittaa sitä vastaavan koodin. Lopussa voi olla vielä else-osa, jonne mennään, jos mikään ehto ei pidä paikkaansa. Esimerkki: Iän tarkistaminen Seuraava ohjelma kysyy käyttäjän iän ja tulostaa siitä kommentin alla olevan taulukon mukaisesti. ikä alle 0 kommentti Ikä ei ole mahdollinen! Olet vielä nuori! Olet keski-ikäinen! Olet jo vanha! yli 120 Ikä ei ole mahdollinen! System.out.print("Kuinka vanha olet? "); int ika = Integer.parseInt(input.nextLine()); if (ika < 0 ika > 120) { System.out.println("Ikä ei ole mahdollinen!"); else if (ika <= 30) { System.out.println("Olet vielä nuori!"); else if (ika <= 70) { System.out.println("Olet keski-ikäinen!"); else { System.out.println("Olet jo vanha!"); Esimerkkejä ohjelman suorituksesta: Kuinka vanha olet? 15 Olet vielä nuori! Kuinka vanha olet? 47 Olet keski-ikäinen!

15 Kuinka vanha olet? -2 Ikä ei ole mahdollinen! Varmista, että ymmärrät kokonaan yllä olevan koodin toiminnan. Ohjelma valitsee ensimmäisen paikkansa pitävän ehdon ja suorittaa sitä vastaavan koodin. Myöhempien ehtojen koodeja ei suoriteta, vaikka ehdot pitäisivät paikkansa. Sisentäminen Sisentäminen tarkoittaa, että koodirivien alkuun laitetaan välilyöntejä koodin rakenteen mukaisesti. Esimerkiksi if-rakenteen sisällä oleva koodi on tapana sisentää, jolloin koodista näkee helposti, miten if-rakenne on muodostunut. Sisentäminen saattaa tuntua aluksi turhalta, mutta sitä oppii kyllä arvostamaan myöhemmin. NetBeansin avulla sisentämisen opetteleminen on helppoa, koska voit painaa Shift + Alt + F, jolloin koodi sisentyy automaattisesti. Merkkijonojen vertailu Seuraava koodi vaikuttaa luontevalta, mutta se ei toimi! if (salasana == "kissa") { System.out.println("Oikein meni!"); Vaikka Java hyväksyy koodin, if-rakenne ei tunnista tilannetta, jossa muuttujassa salasana on merkkijono "kissa". Ilmiön syy selviää myöhemmin kurssilla, mutta tällä hetkellä riittää tietää, että seuraava koodi toimii: if (salasana.equals("kissa")) { System.out.println("Oikein meni!"); Metodit Metodi Metodi on nimetty koodinpätkä, jota voi kutsua muualta koodista. Metodeja käyttämällä samanlaista koodia ei tarvitse kopioida moneen paikkaan ohjelmassa. Lisäksi ohjelma on usein ymmärrettävämpi, kun sen toiminta jakaantuu pienempiin itsenäisiin osiin. Metodin määrittely Seuraava ohjelma tulostaa kolme kuusta peräkkäin: public class KolmeKuusta { public static void main(string[] args) { System.out.println(" *"); System.out.println(" ***"); System.out.println("*****"); System.out.println(" *"); System.out.println(); System.out.println(" *"); System.out.println(" ***"); System.out.println("*****"); System.out.println(" *"); System.out.println(); System.out.println(" *"); System.out.println(" ***"); System.out.println("*****"); System.out.println(" *"); System.out.println(); Ohjelman tulostus on seuraava:

16 * *** ***** * * *** ***** * * *** ***** * Ohjelma toimii kyllä hyvin, mutta samanlainen kuusen tulostava koodi on kopioitu kolme kertaa peräkkäin. Tätä ratkaisua ei voi pitää tyylikkäänä. Seuraavassa muokatussa ohjelmassa on metodi tulostakuusi, joka tulostaa kuusen kerran. Nyt riittää kutsua metodia kolme kertaa. public class KolmeKuusta { public static void tulostakuusi() { System.out.println(" *"); System.out.println(" ***"); System.out.println("*****"); System.out.println(" *"); System.out.println(); public static void main(string[] args) { tulostakuusi(); tulostakuusi(); tulostakuusi(); Yllä olevassa ohjelmassa on kaksi metodia: vanha tuttu main-metodi sekä uusi tulostakuusi-metodi. Javassa main-metodilla on erikoismerkitys: ohjelman suoritus alkaa main-metodin alusta ja päättyy main-metodin lopussa. Välissä ohjelma voi suorittaa muita metodeita, jos main-metodi kutsuu niitä. Parametri Seuraavassa ohjelmassa on metodi tervehdi, jonka tarkoituksena on tervehtiä annettua henkilöä. Metodilla on parametri nimi, jonka avulla metodiin voi välittää tervehdittävän henkilön nimen kutsun yhteydessä. Parametria voi ajatella muuttujana, joka on käytettävissä metodin suorituksen ajan. public class Nimitervehdys { public static void tervehdi(string nimi) { System.out.println("Hei, " + nimi + "!"); public static void main(string[] args) { tervehdi("jenna"); tervehdi("kalle"); tervehdi("pauli"); Ohjelman tulostus on seuraava: Hei, Jenna! Hei, Kalle! Hei, Pauli! Joskus metodilla on useita parametreja. Näin on seuraavassa esimerkissä, jossa metodille tulostasumma annetaan kaksi kokonaislukua. Metodi laskee ja tulostaa lukujen summan.

17 public class SummanTulostus { public static void tulostasumma(int a, int b) { System.out.print("Lukujen " + a + " ja " + b); System.out.println(" summa on " + (a + b) + "."); public static void main(string[] args) { tulostasumma(5, 7); tulostasumma(6, 1); tulostasumma(3, 8); Ohjelman tulostus on seuraava: Lukujen 5 ja 7 summa on 12. Lukujen 6 ja 1 summa on 7. Lukujen 3 ja 8 summa on 11. Monta metodia Ohjelmassa voi olla useita metodeita, jotka kutsuvat toisiaan sisäkkäin. Seuraavassa esimerkissä main-metodi kutsuu metodia tervehdikaikkia, joka kutsuu edelleen kolmesti metodia tervehdi. public class Nimitervehdys { public static void tervehdi(string nimi) { System.out.println("Hei, " + nimi + "!"); public static void tervehdikaikkia() { tervehdi("jenna"); tervehdi("kalle"); tervehdi("pauli"); public static void main(string[] args) { tervehdikaikkia(); Ohjelman tulostus on seuraava: Hei, Jenna! Hei, Kalle! Hei, Pauli! Tässä metodi tervehdikaikkia ei varsinaisesti säästä kirjoitusvaivaa, koska sitä kutsutaan vain kerran. Metodin tarkoituksena on kuitenkin selventää ohjelman rakennetta. Metodin nimestä näkee heti, mitä ohjelman suorituksessa tapahtuu. Palautusarvo Metodin palautusarvo on arvo, jonka metodi palauttaa sen kutsukohtaan muualla koodissa. Palautusarvoa voi ajatella parametrien vastakohtana, koska palautusarvon avulla metodi pystyy välittämään tietoa takaisin sen kutsukohtaan. Jos metodilla on palautusarvo, metodin määrittelyssä sanan void tilalla on palautusarvon tyyppi. Lisäksi metodissa on yksi tai useampi arvon palauttava return-komento. Seuraavassa esimerkissä metodeilla tuplaa ja suurempi on palautusarvo.

18 import java.util.*; public class ArvonPalautus { public static Scanner input = new Scanner(System.in); public static int tuplaa(int n) { return n * 2; public static int suurempi(int a, int b) { if (a > b) { return a; else { return b; public static void main(string[] args) { System.out.print("Anna luku: "); int luku = Integer.parseInt(input.nextLine()); int tulos = tuplaa(luku); System.out.println("Tuplattu: " + tulos); System.out.println("Anna kaksi lukua:"); int eka = Integer.parseInt(input.nextLine()); int toka = Integer.parseInt(input.nextLine()); System.out.println("Suurempi: " + suurempi(eka, toka)); Ohjelman suoritus voi olla seuraava: Anna luku: 3 Tuplattu: 6 Anna kaksi lukua: 2 5 Suurempi: 5 Metodille tuplaa annetaan luku, ja metodi palauttaa luvun kaksinkertaisena. Metodille suurempi annetaan kaksi lukua, ja metodi palauttaa luvuista suuremman. Huomaa kaksi erilaista tapaa käyttää metodin palautusarvoa: sen voi sijoittaa muuttujaan tai suoraan tulostuskomennon osaksi. Arvon palauttava metodi on toiminnaltaan hyvin samanlainen kuin funktio matematiikassa. Itse asiassa monissa ohjelmointikielissä metodeita kutsutaan funktioiksi. Metodin lopettaminen Komento return lopettaa metodin suorituksen välittömästi, vaikka se olisi keskellä metodia. Komentoa voi käyttää myös silloin, kun metodi ei palauta arvoa. Silloin komennon ainoa vaikutus on, että metodin suoritus päättyy. Seuraavassa ohjelmassa metodi tervehdi tulostaa "?!" ja päättyy saman tien, jos parametrina annettu nimi on tyhjä. public class Nimitervehdys { public static void tervehdi(string nimi) { if (nimi.equals("") { System.out.println("?!"); return; System.out.println("Hei, " + nimi + "!"); public static void main(string[] args) { tervehdi("aapeli"); tervehdi("maija"); tervehdi("");

19 Ohjelman tulostus on seuraava: Hei, Aapeli! Hei, Maija!?! Totuusarvot metodista Jos metodi palauttaa boolean-tyyppisen totuusarvon (true tai false), sitä voi käyttää if-rakenteen ehtona. Ideana on, että if-rakenteessa oleva koodi suoritetaan, jos ehto on tosi eli true. Seuraavassa ohjelmassa metodi kelvollinenika palauttaa true, jos ikä on välillä , ja false, jos ikä on näiden ulkopuolella. import java.util.*; public class Totuusarvo { public static Scanner input = new Scanner(System.in); public static boolean kelvollinenika(int ika) { if (ika >= 0 && ika <= 120) { return true; else { return false; public static void main(string[] args) { System.out.print("Kuinka vanha olet? "); int ika = Integer.parseInt(input.nextLine()); if (kelvollinenika(ika)) { System.out.println("Kiitos tiedosta!"); else { System.out.println("Ikä ei kelpaa!"); Vastaavan metodin voi myös tehdä lyhyemmin ilman if-rakennetta: public static boolean kelvollinenika(int ika) { return ika >= 0 && ika <= 120; Tehtävät 1 Jos huomaat tehtävissä korjattavaa, lähetä tänne tiketti: 1. Ensimmäinen ohjelma Tee ohjelma, jonka tulostus on seuraava: Heipparallaa! 2. Kuusi Tee ohjelma, jonka tulostus on seuraava:

20 * *** ***** ******* ********* * 3. Tervehtijä Tee ohjelma, jonka tulostus on seuraava: \o/ "Heippa!" / \ 4. Minuutit viikossa Tee ohjelma, joka laskee, montako minuuttia on viikossa. Ohjelmasi tulostuksen tulisi olla seuraava: Viikossa on X minuuttia. Tässä X:n kohdalle tulee ohjelmasi laskema tulos. 5. Nimen toistaminen Tee ohjelma, joka kysyy käyttäjän nimen ja tervehtii sitten häntä kolme kertaa. Ohjelmasi tulisi toimia seuraavasti: Anna nimi: Aapeli Hei vain, Aapeli! Hei vain, Aapeli! Hei vain, Aapeli! 6. Lukujen summa Tee ohjelma, joka kysyy käyttäjältä kaksi lukua ja laskee niiden summan. Ohjelmasi tulisi toimia seuraavasti: Anna luku 1: 7 Anna luku 2: 18 Summa: Lukujen keskiarvo Tee ohjelma, joka kysyy käyttäjältä kaksi lukua ja laskee niiden keskiarvon. Ohjelmasi tulisi toimia seuraavasti: Anna luku 1: 7 Anna luku 2: 18 Keskiarvo: Ympyrän pinta-ala Ympyrän pinta-alan voi laskea seuraavalla kaavalla:

21 pinta-ala = säde 2 * Tee ohjelma, joka kysyy käyttäjältä ympyrän säteen ja laskee sitten sen pinta-alan. Ohjelmasi tulisi toimia seuraavasti: Anna ympyrän säde: 5 Pinta-ala: Vihje: Saat piin arvon Javan muuttujasta Math.PI. 9. Erikoistervehdys Tee ohjelma, joka sanoo Aapelille "Moro!" ja kaikille muille "Hei!" Ohjelmasi tulisi toimia seuraavasti: Anna nimi: Maija Hei! Anna nimi: Aapeli Moro! Anna nimi: Uolevi Hei! 10. Syntymävuosi Tee ohjelma, joka kysyy käyttäjältä syntymävuoden. Jos vuosi on välillä , ohjelma kertoo, montako vuotta käyttäjä täyttää tänä vuonna (2012). Muuten ohjelma tulostaa tekstin "Taidat narrata!" Anna syntymävuosi: 1980 Täytät tänä vuonna 32 vuotta. Anna syntymävuosi: 1865 Taidat narrata! 11. Tunnus ja salasana Tee ohjelma, joka tunnistaa seuraavat käyttäjät: tunnus aapeli maija salasana kissa kana Jos tunnus ja salasana täsmäävät, ohjelma tulostaa tekstin "Tervetuloa!" Muuten ohjelma tulostaa tekstin "Virhe!" Ohjelmasi tulisi toimia seuraavasti: Anna tunnus: maija Anna salasana: kana Tervetuloa! Anna tunnus: aapeli Anna salasana: kana Virhe!

22 Anna tunnus: uolevi Anna salasana: koira Virhe! 12. Kurssin arvosana Kurssin arvosana lasketaan pistemäärästä seuraavasti: pistemäärä arvosana Tee ohjelma, joka kysyy pistemäärän ja ilmoittaa sen perusteella kurssin arvosanan. Ohjelmasi tulisi toimia seuraavasti: Anna pistemäärä: 43 Kurssin arvosana: 3 Anna pistemäärä: 55 Kurssin arvosana: Tervehdys Tee metodi tervehdi, joka tervehtii parametrina annettua henkilöä kolme kertaa. tervehdi("aapeli"); tervehdi("maija"); Hei, Aapeli! Hei, Aapeli! Hei, Aapeli! Hei, Maija! Hei, Maija! Hei, Maija! 14. Hymiön tulostus Tee metodi tulostahymio, jolla voi tulostaa kolme erilaista hymiötä parametrin mukaan. parametri hymiö 1 (_) 2 (O_o) 3 (;_;)

23 tulostahymio(1); tulostahymio(3); tulostahymio(1); tulostahymio(2); (^_^) (;_;) (^_^) (O_o) 15. Viikonpäivä Tee metodi viikonpaiva, jolle annetaan parametrina viikonpäivän numero (1 = maanantai, 2 = tiistai, jne.) ja joka palauttaa vastaavan viikonpäivän nimen. Voit luottaa, että metodille annettava parametri on luku väliltä System.out.println(viikonpaiva(2)); System.out.println(viikonpaiva(4)); System.out.println(viikonpaiva(7)); tiistai torstai sunnuntai 16. Suomesta englanniksi Tee metodi englanniksi, jolle annetaan suomenkielinen sana ja joka palauttaa vastaavan englanninkielisen sanan. Metodisi tulee hallita ainakin seuraava sanasto: suomeksi apina banaani cembalo englanniksi monkey banana harpsichord System.out.println(englanniksi("apina")); System.out.println(englanniksi("cembalo")); System.out.println(englanniksi("apina")); System.out.println(englanniksi("banaani")); monkey harpsichord monkey banana 17. Pienin kahdesta Tee metodi pienin2, jolle annetaan parametrina kaksi kokonaislukua ja joka palauttaa niistä pienemmän.

24 System.out.println(pienin2(2, 5)); System.out.println(pienin2(5, 2)); System.out.println(pienin2(3, 3)); Pienin kolmesta Tee metodi pienin3, jolle annetaan parametrina kolme kokonaislukua ja joka palauttaa niistä pienimmän. System.out.println(pienin3(3, 2, 8)); System.out.println(pienin3(5, 7, 9)); System.out.println(pienin3(5, 2, 2)); System.out.println(pienin3(8, 8, 1)); Vihje: Voit halutessasi hyödyntää edellisen tehtävän metodia pienin Nopan heitto Tee metodi heitanoppaa, joka palauttaa satunnaisen nopan silmäluvun väliltä System.out.println(heitaNoppaa()); System.out.println(heitaNoppaa()); System.out.println(heitaNoppaa()); System.out.println(heitaNoppaa()); Koodin tulostus voi olla esimerkiksi seuraava: Vihje: Tässä on hyödyllinen apumetodi, joka palauttaa satunnaisen kokonaisluvun alarajan ja ylärajan väliltä: public static int arvoluku(int alaraja, int ylaraja) { return alaraja + (int)(math.random() * (ylaraja - alaraja + 1)); 20. Rahan heitto Tee metodi heitarahaa, joka palauttaa satunnaisesti merkkijonon "kruuna" tai "klaava". Seuraava koodi testa metodiasi:

25 System.out.println(heitaRahaa()); System.out.println(heitaRahaa()); System.out.println(heitaRahaa()); System.out.println(heitaRahaa()); Koodin tulostus voi olla esimerkiksi seuraava: kruuna kruuna klaava kruuna 21. Parillisuus Tee metodi parillinen, joka palauttaa arvon true, jos parametrina annettu luku on parillinen, ja muuten arvon false. System.out.println(parillinen(16)); System.out.println(parillinen(17)); System.out.println(parillinen(0)); System.out.println(parillinen(-3)); true false true false Vihje: Jaollisuus kannattaa tarkastaa jakojäännöksen avulla. Voit laskea Javalla jakojäännöksen käyttämällä %-merkkiä. Esimerkiksi lasku 8 % 3 tuottaa tuloksen 2, koska jos 8 jaetaan 3:lla, niin 2 jää yli. 22. Karkausvuosi Tee metodi karkausvuosi, joka palauttaa arvon true, jos parametrina annettu vuosi on karkausvuosi, ja muuten arvon false. Vuosi on karkausvuosi, jos se on jaollinen 4:llä. Kuitenkin jos vuosi on jaollinen 100:lla, se on karkausvuosi vain silloin, kun se on jaollinen myös 400:lla. System.out.println(karkausvuosi(2012)); System.out.println(karkausvuosi(2013)); System.out.println(karkausvuosi(1900)); System.out.println(karkausvuosi(2000)); true false false true 23. Fibonaccin luvut Rekursiossa on ideana, että metodin sisällä on kutsu metodiin itseensä. Tyypillinen esimerkki rekursiosta on kertoman määrittely matematiikassa: \[ n! = \left\{ \begin{array{ll 1 & \textrm{jos $n=0$\\ (n-1)! \cdot n & \textrm{jos $n>0$ \end{array \right. \] Javassa vastaavan voi toteuttaa seuraavasti:

26 public static int kertoma(int n) { if (n == 0) { return 1; else { return kertoma(n - 1) * n; Fibonaccin luvut voidaan määritellä seuraavasti: \[ F(n) = \left\{ \begin{array{ll 0 & \textrm{jos $n=0$\\ 1 & \textrm{jos $n=1$\\ F(n-2)+F(n-1) & \textrm{jos $n \geq 2$ \end{array \right. \] Tee rekursiivinen metodi fibonacci, joka laskee parametrina annetun Fibonaccin luvun. System.out.println(fibonacci(3)); System.out.println(fibonacci(5)); System.out.println(fibonacci(9)); System.out.println(fibonacci(11)); Ackermannin funktio Ackermannin funktio voidaan määritellä seuraavasti: \[ A(m,n) = \left\{ \begin{array{ll n+1 & \textrm{jos $m=0$\\ A(m-1,1) & \textrm{jos $m>0$ ja $n=0$\\ A(m-1,A(m,n-1)) & \textrm{jos $m>0$ ja $n>0$ \end{array \right. \] Tee metodi ackermann, joka laskee Ackermannin funktion arvon annetuilla parametreilla. System.out.println(ackermann(0, 3)); System.out.println(ackermann(3, 0)); System.out.println(ackermann(1, 1)); System.out.println(ackermann(3, 2)); Nopanheitot Luku 4 voidaan muodostaa 8 eri tavalla noppien silmälukujen (1--6) summana: Tee metodi, joka laskee, kuinka monella tavalla annetun positiivisen kokonaisluvun voi muodostaa noppien silmälukujen (1--6) nopat summana.

27 System.out.println(nopat(4)); System.out.println(nopat(8)); System.out.println(nopat(11)); System.out.println(nopat(14)); Vihje: Yritä muotoilla rekursiivinen funktio, joka palauttaa erilaisten heittotapojen määrän annetulla summalla. for-silmukka for-silmukka for-silmukka käy läpi tietyllä välillä olevat luvut ja suorittaa jokaisen luvun kohdalla samanlaisen koodin. Esimerkki Seuraava ohjelma tulostaa kokonaisluvut väliltä : for (int i = 1; i <= 100; i++) { System.out.println(i); Ohjelman tulostus on seuraava: (välissä rivejä) Tässä silmukassa muuttujan i arvoksi tulee vuorollaan kukin kokonaisluku välillä Silmukan sisällä oleva koodi tulostaa muuttujan i arvon. Seuraavaksi selviää, miten for-silmukka toimii tarkkaan ottaen. Yleinen muoto Yleinen for-silmukan muoto on seuraava: for ([alkuarvo]; [jatkamisehto]; [muutos]) { [koodi] Kohdassa [alkuarvo] määritellään muuttuja, jolle annetaan alkuarvoksi ensimmäinen läpikäytävä luku. Yllä olevassa esimerkissä määriteltiin muuttuja i, jolle annettiin alkuarvoksi 1. Kohdassa [jatkamisehto] kerrotaan, miten kauan for-silmukka jatkuu. Yllä olevassa esimerkissä ehtona oli, että muuttujan arvo on korkeintaan 100. Kohdassa [muutos] muutetaan muuttujaa halutulla tavalla. Yllä olevassa esimerkissä muuttujan arvoa kasvatettiin aina yhdellä. Seuraavassa on esimerkkejä erilaisista for-silmukoista: silmukka tulostus

28 for (int i = 1; i < 5; i++) { System.out.println(i); for (int i = 1; i <= 5; i++) { System.out.println(i); for (int i = 1; i <= 5; i += 2) { System.out.println(i); for (int i = 5; i > 1; i--) { System.out.println(i); for (int i = 5; i >= 1; i--) { System.out.println(i); for (int i = 5; i >= 1; i -= 2) { System.out.println(i); Mieti jokaisesta yllä olevasta silmukasta, miksi se tulostaa annetut luvut. Tämän jälkeen voit siirtyä eteenpäin. Esimerkki: Viestin toisto Seuraava ohjelma toistaa käyttäjän antaman viestin halutun määrän kertoja:

29 System.out.print("Anna viesti: "); String viesti = input.nextline(); System.out.print("Anna toistokerrat: "); int kerrat = Integer.parseInt(input.nextLine()); for (int i = 0; i < kerrat; i++) { System.out.println(viesti); Ohjelman tulostus voi olla seuraava: Anna viesti: Kappas kippis! Anna toistokerrat: 5 Kappas kippis! Kappas kippis! Kappas kippis! Kappas kippis! Kappas kippis! Tässä tapauksessa for-silmukassa olevaa muuttujaa i ei käytetty mitenkään silmukan sisällä olevassa koodissa. Silmukan ainoa tarkoitus oli suorittaa sama koodi halutun määrän kertoja. Esimerkki: Kuusi Seuraavassa esimerkissä for-silmukan sisällä on if-rakenne. Ohjelma tulostaa kokonaisluvut väliltä , mutta luvun 6 kohdalla ohjelma tulostaa kuusen kuvan. for (int i = 1; i <= 10; i++) { if (i == 6) { System.out.println(" *"); System.out.println(" ***"); System.out.println("*****"); System.out.println(" *"); else { System.out.println(i); Ohjelman tulostus on seuraava: * *** ***** * Esimerkki: Kolmen luvun summa Usein for-silmukkaan liittyy muuttujia, joita käytetään myös silmukan ulkopuolella. Seuraava ohjelma kysyy käyttäjältä kolme lukua ja ilmoittaa lopuksi niiden summan.

30 System.out.println("Ohjelma kysyy sinulta kolme lukua..."); int summa = 0; for (int i = 1; i <= 3; i++) { System.out.print("Anna luku " + i + ": "); int luku = Integer.parseInt(input.nextLine()); summa = summa + luku; System.out.println("Lukujen summa: " + summa); Ohjelman suoritus voi olla seuraava: Ohjelma kysyy sinulta kolme lukua... Anna luku 1: 5 Anna luku 2: 2 Anna luku 3: 8 Lukujen summa: 15 Huomaa muuttujan summa käyttötapa: muuttujan arvo on aluksi 0, ja sitten siihen lisätään yksi kerrallaan käyttäjän antamia lukuja. Yllä olevassa tilanteessa muuttujan arvo muuttuu seuraavasti: Aluksi summa on 0. Käyttäjä antaa luvun 5, jolloin summa on = 5. Käyttäjä antaa luvun 2, jolloin summa on = 7. Käyttäjä antaa luvun 8, jolloin summa on = 15. Ymmärräthän varmasti, mihin koodin toiminta perustuu? Muuttujan nimi Tähän mennessä kaikissa esimerkeissä for-silmukan muuttujan nimi on ollut i. Näin ei ole kuitenkaan pakko olla, vaan nimi voi olla mikä tahansa kelvollinen muuttujan nimi. Kuitenkin yleiseksi tavaksi ohjelmoinnissa on tullut, että for-silmukan muuttujan nimeksi valitaan usein i. Esimerkki: Vuodet ja kuukaudet Joskus for-silmukkoja on useampia sisäkkäin. Näin on seuraavassa esimerkissä, joka käy läpi vuosien kuukaudet. Ulompi silmukka käy läpi vuosia, ja sisempi silmukka käy läpi kuukausia. for (int vuosi = 2010; vuosi <= 2015; vuosi++) { for (int kuukausi = 1; kuukausi <= 12; kuukausi++) { System.out.println(kuukausi + "/" + vuosi); Ohjelman tulostus on seuraava: 1/2010 2/2010 3/2010 (välissä rivejä) 10/ / /2010 1/2011 2/2011 3/2011 (välissä rivejä) 10/ / /2015 Merkkijonot Merkkijono ja merkki

31 Merkkijonon tietotyyppi String on tullut tutuksi jo aiemmissa luvuissa. Tämän lisäksi Javassa on tietotyyppi char, joka vastaa yhtä merkkiä. Seuraava koodi määrittelee ja tulostaa char-muuttujan: char merkki = 'A'; System.out.println(merkki); Ohjelman tulostus on seuraava: A Erona String-muuttujaan verrattuna char-muuttujassa on aina tasan yksi merkki, joka kirjoitetaan heittomerkkien sisään. Merkkijonon koostumus Merkkijonoon liittyvät seuraavat tärkeät komennot: length kertoo merkkijonon pituuden (merkkien määrän). charat kertoo tietyssä kohdassa olevan merkin. Esimerkiksi merkkijono "testi" on muistissa seuraavasti: kohta merkki t e s t i Seuraava ohjelma esittelee komentojen käyttöä: System.out.print("Anna merkkijono: "); String merkkijono = input.nextline(); int pituus = merkkijono.length(); System.out.println("Pituus: " + pituus); char eka = merkkijono.charat(0); System.out.println("Ensimmäinen merkki: " + eka); char vika = merkkijono.charat(merkkijono.length() - 1); System.out.println("Viimeinen merkki: " + vika); System.out.println("Kaikki merkit:"); for (int i = 0; i < merkkijono.length(); i++) { char merkki = merkkijono.charat(i) ; System.out.println("Kohdassa " + i + " on merkki " + merkki); Ohjelman tulostus voi olla seuraava: Anna merkkijono: testi Pituus: 5 Ensimmäinen merkki: t Viimeinen merkki: i Kaikki merkit: Kohdassa 0 on merkki t Kohdassa 1 on merkki e Kohdassa 2 on merkki s Kohdassa 3 on merkki t Kohdassa 4 on merkki i Osa merkkijonosta Komennolla substring pystyy erottamaan osan merkkijonosta. Komentoa voi käyttää kahdella tavalla: substring(alku) erottaa merkit kohdasta alku merkkijonon loppuun asti. substring(alku, loppu) erottaa merkit kohdasta alku kohtaan loppu-1 asti. Seuraavassa esimerkissä merkkijono on muistissa näin: kohta

32 merkki e s i m e r k k i Erotetaan merkkijonosta kaksi osaa: String merkkijono = "esimerkki"; String osa1 = merkkijono.substring(3); System.out.println(osa1); String osa2 = merkkijono.substring(2, 7); System.out.println(osa2); Ohjelman tulostus on seuraava: merkki imerk Huomaa komennon erikoinen toiminta, kun lopetuskohta annetaan: viimeinen mukaan tuleva merkki on yksi merkki ennen lopetuskohtaa! Haku merkkijonosta Komento indexof etsii kohdan, jossa merkkijonon osana on tietty merkki tai merkkijono. Jos kohtia on useita, komento kertoo ensimmäisen kohdan. Jos yhtään kohtaa ei ole, komento tuottaa arvon -1. Seuraava ohjelma hakee merkkijonosta "esimerkki" käyttäjän antamaa merkkijonoa. String merkkijono = "esimerkki"; System.out.print("Anna haettava merkkijono: "); String haettava = input.nextline(); int kohta = merkkijono.indexof(haettava); if (kohta == -1) { System.out.println("Haettavaa merkkijonoa ei ole"); else { System.out.println("Haettava merkkijono alkaa kohdassa " + kohta); Esimerkkitulostuksia: Anna haettava merkkijono: merkki Haettava merkkijono alkaa kohdassa 3 Anna haettava merkkijono: merkki Haettavaa merkkijonoa ei ole Merkkikoodit Javassa jokaista merkkiä vastaa merkkikoodi, joka on kokonaisluku. Esimerkiksi merkkiä 'A' vastaa merkkikoodi 65. Niinpä char-arvolla on kaksi vaihtoehtoista merkintätapaa: merkkiesitys ja koodiesitys. Seuraavassa taulukossa on osa Javan merkistöstä merkkikoodeineen:

33 33! 34 " 35 # 36 $ 37 % 38 & 39 ' 40 ( 41 ) 42 * , / : 59 ; 60 < 61 = 62 > 63? 65 A 66 B 67 C 68 D 69 E 70 F 71 G 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w 120 x 121 y 122 z Merkin merkkikoodin saa selville näin: char merkki = 'A'; System.out.println("Merkkikoodi: " + (int)merkki); Vastaavasti merkkikoodin merkin saa selville näin: int koodi = 65; System.out.println("Merkki: " + (char)koodi); Seuraava koodi tulostaa kirjaimet väliltä A...Z: for (char i = 'A'; i <= 'Z'; i++) { System.out.print(i); System.out.println(); Ohjelman tulostus on seuraava: ABCDEFGHIJKLMNOPQRSTUVWXYZ Kuten tästä esimerkistä havaitaan, char-arvoja voi käsitellä hyvin samalla tavalla kuin lukuarvoja. Matematiikka Laskutoimituksia Jakojäännös Jakojäännös tarkoittaa jakolaskussa yli jäävää kokonaislukua. Esimerkiksi jos luku 17 jaetaan luvulla 5, jakojäännös on 2, koska 3 5 = 15, mutta 2 jää yli. Javassa jakojäännös lasketaan %-merkillä. Esimerkiksi laskun 17 % 5 tulos on 2. Tavallinen jakojäännöksen sovellus ohjelmoinnissa on luvun jaollisuuden tarkistaminen. Luku on jaollinen n:llä tarkalleen silloin, kun sen jakojäännös n:llä on 0. Potenssilasku Metodi Math.pow(a, b) laskee potenssilaskun a b. Esimerkiksi laskun Math.pow(2, 3) tulos on 8. Huomaa, että metodi palauttaa double-arvon. Jos korotettava potenssi on pieni kokonaisluku, voi olla helpompi ratkaisu korvata potenssilasku kertolaskulla. Esimerkiksi a 2 tarkoittaa samaa kuin a * a. Huom! Javassa on operaattori ^, mutta se ei ole potenssilasku. Merkintä ^ tarkoittaa bitittäistä xor-laskua, jota ei käsitellä tällä kurssilla.

34 Neliöjuuri Metodi Math.sqrt(a) laskee luvun a neliöjuuren. Itseisarvo Metodi Math.abs(a) laskee luvun a itseisarvon. Suurempi ja pienempi Metodit Math.max(a, b) ja Math.min(a, b) palauttavat suuremman ja pienemmän kahdesta luvusta. Satunnaisluvut Helpoin tapa tuottaa satunnaislukuja Javassa on käyttää metodia Math.random(), joka palauttaa satunnaisen desimaaliluvun x, jolle pätee 0 x < 1. Tämän avulla voi tehdä metodin, joka palauttaa satunnaisen kokonaisluvun annetun alarajan ja ylärajan väliltä: public static int arvoluku(int alaraja, int ylaraja) { return alaraja + (int)(math.random() * (ylaraja - alaraja + 1)); Kaavassa on ideana, että alarajaan lisätään satunnainen kokonaisluku sellaiselta väliltä, että pienimmillään tulos on alaraja ja suurimmillaan yläraja. Esimerkki: Piin arviointi Huom: Tämä esimerkki on suunnattu matemaatikoille yms. Esimerkin ymmärtäminen ei ole tärkeää kurssin kannalta. Seuraava ohjelma arvioi piin arvoa satunnaislukujen avulla. Ohjelma arpoo miljoona pisteparia (x, y), jossa 0 x, y < 1. Jos piste osuu kohdassa (0, 0) olevan ympyrän sisään, jonka säde on 1, ohjelma kasvattaa laskuria. Lopulta arvio piin arvolle saadaan ympyrän ja neliön pinta-alojen suhteen avulla. int maara = ; int laskuri = 0; for (int i = 0; i < maara; i++) { double x = Math.random(); double y = Math.random(); double matka = Math.sqrt(x * x + y * y); if (matka < 1) { laskuri++; double pii = 4 * (double)laskuri / maara; System.out.println(pii); Ohjelman tulostus voi olla seuraava: Lukuarvot Javan tyypit int ja double tuntuvat päältä päin melko samanlaisilta, mutta niiden käytössä on silti tärkeitä eroja. Tyyppi int tallentaa kokonaisluvun tarkasti, mutta sen lukualue on melko rajattu: pienin mahdollinen int-luku on ja suurin mahdollinen int-luku on Seuraavan ohjelman toiminta on yllättävä: int luku = ; luku = luku + 1; System.out.println(luku); Ohjelma tulostaa luvun Tässä int-muuttujaan yritettiin laittaa liian suuri luku, jolloin luvun arvo pyörähti ympäri negatiiviselle puolelle pienimpään mahdolliseen lukuun.

35 Suurempia kokonaislukuja varten Javassa on tyypit long ja BigInteger, mutta käytännössä int on silti usein riittävä tyyppi. Tyyppi double voi sisältää desimaaliluvun ja sen lukualue on suuri, mutta tyypin rajoituksena on, että monen luvun arvoa ei voida tallentaa tarkasti vaan arvo joudutaan pyöristämään. Niinpä double-tyyppiä käyttäessä harmina ovat mahdolliset pyöristysvirheet. Seuraava ohjelma saa aikaan pyöristysvirheen: double luku = 0.2; luku = luku + 0.1; System.out.println(luku); Ohjelman tulostus on seuraava: Pyöristysvirheen vuoksi luku on eikä 0.3. Tehtävät 2 Jos huomaat tehtävissä korjattavaa, lähetä tänne tiketti: 1. Lukuvälin tulostus Tee ohjelma, joka kysyy käyttäjältä alarajan ja ylärajan ja tulostaa näiden välissä olevat luvut. Ohjelmasi tulisi toimia seuraavasti: Anna alaraja: 5 Anna yläraja: Lukuvälin summa Tee ohjelma, joka kysyy käyttäjältä alarajan ja ylärajan ja tulostaa näiden välissä olevien lukujen summan. Ohjelmasi tulisi toimia seuraavasti: Anna alaraja: 5 Anna yläraja: Yllä olevassa tapauksessa = 56. Osaatko tehdä ohjelman käyttämättä silmukkaa? 3. Lähtölaskenta Tee ohjelma, joka tulostaa lähtölaskennan käyttäjän antamasta positiivisesta kokonaisluvusta nollaan asti. Mutta jos käyttäjä antaa luvun, joka on yli 20, ohjelma sanoo "En jaksa laskea!" Ohjelmasi tulisi toimia seuraavasti: Anna luku: