Tämä materiaali on lisensoitu Creative Commons BY-NC-SA-lisenssillä, joten voit käyttää ja levittää sitä vapaasti, kunhan alkuperäisten tekijöiden nimiä ei poisteta. Jos teet muutoksia materiaaliin ja haluat levittää muunneltua versiota, se täytyy lisensoida samanlaisella vapaalla lisenssillä. Materiaalien käyttö kaupalliseen tarkoitukseen on ilman erillistä lupaa kielletty.
Tekijät: Arto Vihavainen ja Matti Luukkainen
Olemassaolevan muuttujan arvoa halutaan usein muuttaa. Tämä onnistuu tavallisen sijoituslausekkeen avulla. Seuraavassa muuttujan ika
arvoa kasvatetaan yhdellä:
int ika = 1; System.out.println( ika ); // tulostuu 1 ika = ika + 1; // ika:n uusi arvo on ika:n vanha arvo plus yksi System.out.println( ika ); // tulostuu 2
Komento ika = ika + 1
siis kasvattaa muuttujan ika
arvoa yhdellä. Muuttujan arvon kasvattaminen yhdellä onnistuu myös seuraavasti:
int ika = 1; System.out.println( ika ); // tulostuu 1 ika++; // tarkoittaa samaa kuin ika = ika + 1; System.out.println( ika ); // tulostuu 2
Toinen esimerkki:
int pituus = 100; System.out.println( pituus ); // tulostuu 100 pituus = pituus - 50; System.out.println( pituus ); // tulostuu 50 pituus = pituus * 2; System.out.println( pituus ); // tulostuu 100 pituus = pituus / 4; System.out.println( pituus ); // tulostuu 25 pituus--; // sama kuin pituus = pituus-1; System.out.println( pituus ); // tulostuu 24
Tee ohjelma, joka kysyy käyttäjältä kolme lukua ja tulostaa niitten summan. Tee ohjelmastasi seuraavan muotoinen:
Scanner lukija = new Scanner(System.in); int summa = 0; int luettu; // KIRJOITA OHJELMA TÄHÄN // ÄLÄ KÄYTÄ MUITA MUUTTUJIA KUIN lukija, summa JA luettu! System.out.println("Summa: "+summa);
Anna ensimmäinen luku: 3 Anna toinen luku: 6 Anna kolmas luku: 12 Summa: 21
Tee ohjelma, joka lukee käyttäjältä lukuja ja tulostaa niiden summan. Ohjelma lopettaa kyselemisen kun syötetään luku 0. Käytä seuraavaa pohjaa, jonka saat myös palautusautomaatilta:
Scanner lukija = new Scanner(System.in); int summa = 0; System.out.print("Anna lukuja, nolla lopettaa: "); while (true) { int luettu = Integer.parseInt(lukija.nextLine()); if (luettu == 0) { break; } // TEE JOTAIN TÄÄLLÄ System.out.println("Summa nyt: "+summa); } System.out.println("Summa lopussa: "+summa);
Ohjelman tulee toimia seuraavasti:
Anna lukuja, nolla lopettaa: 3 Summa nyt: 3 2 Summa nyt: 5 1 Summa nyt: 6 1 Summa nyt: 7 0 Summa lopussa: 7
Opimme aiemmin toteuttamaan while(true)
-komennon avulla ohjelman, joka toistaa tiettyä komentosarjaa komennon break
suorittamiseen asti.
Komento break
ei ole ainoa tapa lopettaa toistoa. Toistokomennon yleinen muoto on while (ehto)
, jossa ehtona voi olla mikä tahansa totuusarvoinen lauseke, eli ehto voi olla täsmälleen samaa muotoa kuin if
-komentojen ehdot.
Seuraavassa esimerkissä tulostetaan luvut 1, 2, ..., 10. Kun luku
-muuttuja saa arvokseen yli 10, while
-ehto ei ole enää voimassa ja toistaminen lopetetaan.
int luku = 1; while (luku < 11) { System.out.println(luku); luku++; // luku++ tarkoittaa samaa kuin luku = luku + 1 }
Lue ylläoleva "niin pitkään kuin luku on pienempi kuin 11, tulosta luku ja kasvata lukua yhdellä".
Ylläolevassa koodissa ehdossa olevaa muuttujaa luku
kasvatettiin jokaisella kierroksella
yhdellä. Päivitys voi olla mikä tahansa, eli ehdossa olevan muuttujan ei tarvitse suinkaan aina kasvaa yhdellä, esim:
int luku = 1024; while (luku >= 1) { System.out.println(luku); luku = luku / 2; }
Screencast aiheesta:
Jos ohjelmassasi on käytössä esim. muuttuja String sukunimi;
, ei koko muuttujan nimeä tarvitse välttämättä joka kerta kirjoittaa kokonaan. Kokeile mitä tapahtuu kun kirjoitat s
ja sen jälkeen painat yhtäaikaa ctrl ja välilyönti. HUOM: laitoksen koneilla automaattinen täydennys saadaan aikaan painamalla yhtä aikaa ctrl, alt ja välilyönti.
Vastaavalla tavalla NetBeans osaa täydentää muitakin nimiä, esim. komennon while
aikaansaamiseksi riittää kirjoittaa w ja painaa ctrl+välilyönti...
Muista että saat ruudulle tekstin System.out.println("") kirjoittamalla sout ja painamalla tabulaattoria eli q:n vasemmalla puolella olevaa näppäintä
HUOM2: Pääset tarkastelemaan NetBeansin valmiiksi määrittelemiä lyhenteitä seuraavasti:
Tools -> Options -> Editor -> Code Templates
Pystyt myös lisäämään omia lyhenteitäsi New painikkeella.
Voi luoda itsellesi esimerkiksi uuden komennon ipn
int ${luku newVarName} = Integer.parseInt(${lukija instanceof="java.util.Scanner"}.nextLine());
Nyt kirjoittamalla ipn pitäisi ruudulle ilmestyä jotakin tämän tapaista:
int i = Integer.parseInt(lukija.nextLine());
Tee seuraavat tehtävät while-komennon avulla:
Tee ohjelma, joka tulostaa kokonaisluvut väliltä 1–100.
Ohjelman tulostus on seuraava:
1 2 3 (välissä paljon rivejä) 98 99 100
Tee ohjelma, joka tulostaa kokonaisluvut väliltä 100–1.
Ohjelman tulostus on seuraava:
100 99 98 (välissä paljon rivejä) 3 2 1
Vihje: aseta toistossa käytettävän apumuuttujan arvoksi aluksi 100 ja vähennä muuttujan arvoa yhdellä toiston sisällä.
Tee ohjelma, joka tulostaa parilliset kokonaisluvut väliltä 2–100.
2 4 6 (välissä paljon rivejä) 96 98 100
Kirjoita ohjelma, joka tulostaa kokonaisluvut 1:stä käyttäjän antamaan lukuun asti.
Mihin asti? 3 1 2 3
Mihin asti? 5 1 2 3 4 5
Vihje: käyttäjältä lukemasi luku toimii nyt whilen lopetusehdon ylärajana. Muista että Javassa a <= b
tarkoittaa a pienempi tai yhtä suuri kuin b.
Lisää ohjelmaan käyttäjältä kysyttävä alaraja.
Mihin asti? 8 Mistä lähtien? 5 5 6 7 8
Jos tavoite on suurempi kuin lähtökohta ei tulostu mitään:
Mihin asti? 12 Mistä lähtien? 16
Huom! muista että ala- ja yläraja voivat olla myös negatiivisia!
Robotti on taas täällä! Käytössä olevat komennot ovat Ohjain.kaynnista()
, Ohjain.sammuta()
, Ohjain.vasen()
, Ohjain.oikea()
ja Ohjain.liiku()
.
Kirjoita ohjelma, joka kysyy käyttäjältä piirrettävien portaiden lukumäärää.
Kun käyttäjä syöttää esimerkiksi luvun kolme, tulee robotin piirtää kolme porrasaskelmaa.
Montako ylös? 3
Täydennä ohjelmaa siten, että robotti kulkee portaita myös alas.
Alla olevassa esimerkissä robotti nousee ensin viisi askelta ylös, ja laskeutuu sitten kaksi askelta alas.
Montako ylös? 5 Montako alas? 3
Koska vanhan muuttujan arvon muuttaminen on hyvin yleinen operaatio, on Javassa sitä varten erityiset sijoitusoperaatiot.
int pituus = 100; pituus += 10; // sama kuin pituus = pituus + 10; pituus -= 50; // sama kuin pituus = pituus - 50;
Olemassaolevan muuttujan arvoa muuttava sijoitusoperaatio merkitään muuttuja muutostyyppi= muutos
, esimerkiksi muuttuja += 5
. Huomaa, että muuttujan tyyppi pitää aina kertoa ennen kuin sille voidaan asettaa arvo. Muuttuja tulee siis aina esitellä ennen kuin se on käytettävissä. Muuttujan esittely tapahtuu kertomalla muuttujan tyyppi ja nimi.
Seuraava esimerkki ei toimi, sillä muuttujan pituus
tyyppiä ei ole kerrottu.
pituus = pituus + 100; // ei toimi! pituus += 100; // ei toimi!
Kun tyyppi on kerrottu, laskutkin toimivat oikein.
int pituus = 0; pituus = pituus + 100; pituus += 100; // muuttujan pituus arvo on 200
Myös muille kuin yhteen- ja vähennyslaskuille on Javassa vastaavat sijoitusoperaatiot.
int pituus = 100; pituus *= 10; // sama kuin pituus = 10 * pituus; pituus /= 100; //sama kuin pituus = pituus / 100; pituus %= 3; // sama kuin pituus = pituus % 3; // muuttujan pituus arvo 1
Usein ohjelmissa esiintyy toisto jonka aikana muuttujaan lasketaan jokin toistosta riippuvainen arvo. Seuraava ohjelma laskee tulon 4*3 hieman kömpelöllä tavalla eli summana 3+3+3+3:
int tulos = 0; int i = 0; while ( i < 4 ) { tulos = tulos + 3; i++; // tarkoittaa samaa kuin i = i+1; }
Alussa tulos = 0
. Toistossa muuttujan arvo nousee joka kierroksella 3:lla. Ja koska toistoja on 4, on lopulta muuttujan arvona siis 3*4.
Käyttämällä yllä esiteltyä sijoitusoperaattoria, sama saadaan aikaan seuraavasti:
int tulos = 0; int i = 0; while ( i < 4 ) { tulos += 3; // tämä on siis sama kuin tulos = tulos + 3; i++; // tarkoittaa samaa kuin i = i+1; }
Tee ohjelma, joka laskee summan 1+2+3+...+n, missä n on käyttäjän syöttämä luku.
Esimerkkitulostuksia:
Mihin asti? 3 Summa on 6
Edellisessä esimerkissä laskettiin 1+2+3 = 6
Mihin asti? 7 Summa on 28
Ja nyt laskettiin 1+2+3+4+5+6+7 = 28
Vihje: Tee ohjelma while
-komennon avulla. Käytä ohjelmassasi apumuuttujaa toistokertojen muistamiseen. Lisää jokaisella toistokerralla toistokerrat muistavan muuttujan arvo apumuuttujaan johon lasket summan arvon.
Muuta edellistä tehtävää siten, että käyttäjä määrää summan laskemisen aloituskohdan. Voit olettaa, että käyttäjä antaa ensin pienemmän luvun ja sitten suuremman luvun.
Esimerkkitulostuksia:
Ensimmäinen: 3 Viimeinen: 5 Summa on 12
Ensimmäinen: 2 Viimeinen: 8 Summa on 35
Tee ohjelma, joka laskee luvun n kertoman. Kertoma n! lasketaan kaavalla 1*2*3*...*n. Esimerkiksi 4! = 1*2*3*4 = 24. Lisäksi on määritelty, että 0! = 1.
Esimerkkitulostuksia:
Anna luku: 3 Kertoma on 6
Anna luku: 10 Kertoma on 3628800
Tee ohjelma, joka laskee summan 20+21+22+...+2n,
missä n on käyttäjän syöttämä luku.
Merkintä 2i tarkoittaa luvun 2 korottamista potenssiin i,
esimerkiksi 24 = 2*2*2*2 = 16.
Javassa merkintä ab ei ole käytössä,
mutta potenssin voi laskea komennolla Math.pow(luku, potenssi)
. Huom. komento palauttaa double
-tyyppisen eli liukulukutyyppisen luvun. Liukulukutyyppisen luvun voi muuttaa kokonaisluvuksi ( int
-tyyppiseksi ) seuraavasti: int tulos = (int) Math.pow(2, 3)
. Lasku asettaa muuttujaan tulos laskun 2 potenssiin 3 arvon.
Esimerkkitulostuksia:
Anna luku: 3 Tulos on 15
Anna luku: 7 Tulos on 255
Yksi suosituimmista ohjelmointivirheistä toistolauseissa on tehdä vahingossa ikuinen silmukka. Seuraavassa yritetään tulostaa ruudulle 10 kertaa "En enää ikinä ohjelmoi ikuista silmukkaa":
int i = 0; while( i<10 ) { System.out.println("En enää ikinä ohjelmoi ikuista silmukkaa"); }
Toistokertojen määrää kontrolloiva muuttuja i
on aluksi 0 ja toistoja on tarkoitus tehdä niin kauan kuin i<10
. Käy kuitenkin hieman hassusti: muuttujan i
arvoa ei muuteta missään, joten toistoehto pysyy ikuisesti totena.
Olemme tehneet peräkkäin jo muutamia toistotehtäviä, joissa toistoehto on muotoa:
int i = 1; while ( i < 10 ) { // ... i++; }
Ylläolevassa rungossa muuttuja i
muistaa toistokertojen määrän, ja lopetusehto perustuu i
:n vertailuun.
Muistellaan taas toiston lopetusta. Toiston lopetuksen ei tarvitse perustua toistokertojen laskemiseen. Katsotaan esimerkkiä jossa kysytään käyttäjän ikää. Jos ikä ei ole välillä 1-120, annetaan huomautus ja kysytään ikä uudelleen. Toistolauseen while-lauseen ehto voi siis olla mitä tahansa totuusarvon tuottavaa.
System.out.println("ikäsi: "); int ika = Integer.parseInt(lukija.nextLine()); while( ika < 1 || ika > 120 ) { // ikä pienempi kuin 5 TAI suurempi kuin 120 System.out.println("Valehtelet"); if ( ika < 1 ) { System.out.println("Olet niin nuori ettet osaa kirjoittaa"); } else if ( ika > 120 ) { System.out.println("Olet niin vanha ettet osaa käyttää tietokonetta"); } System.out.println("syötä ikäsi uudelleen: "); ika = Integer.parseInt(lukija.nextLine(); } System.out.println("Ikäsi on siis "+ ika);
Ohjelman olisi voinut tehdä myös vanhaa tuttua while(true)
-rakennetta käyttäen:
System.out.println("ikäsi: "); while( true ) { int ika = Integer.parseInt(lukija.nextLine()); if ( ika >= 1 && ika <= 120 ) { // ikä 1:n JA 120:n välillä break; // lopetetaan toisto } System.out.println("Valehtelet"); if ( ika < 1 ) { System.out.println("Olet niin nuori ettet osaa kirjoittaa"); } else { // ikä siis yli 120 System.out.println("Olet niin vanha ettet osaa käyttää tietokonetta"); } System.out.println("syötä ikäsi uudelleen: "); } System.out.println("Ikäsi on siis "+ ika);
Tämä tehtäväsarja muodostaa yhden isomman ohjelman, jonka toiminnallisuus toteutetaan pienissä paloissa. Jos et tee tehtäväsarjaa loppuun asti, voit lähettää sen tarkastettavaksi vajaatekoisenakin. Tämä onnistuu painamalla testausnapin oikealla puolella olevasta "submit"-napista eli pienestä ylöspäinosoittavasta nuolesta. Vaikka palautusautomaatti valittaakin vielä tekemättä olevien tehtävänosien testeistä, kirjautuvat jo tekemiesi osien pisteet.
Huom: nyt (ja jatkossa) jokainen isomman tehtävän "alitehtävä" (kuten 36.1) on saman arvoinen tehtävä kuin alikohdaton tehtävä. Tehtävä 36 siis vastaa viittä normaalia tehtävää.
Tee ohjelma, joka kysyy käyttäjältä lukuja (ohjelma tulostaa käyttäjälle aluksi "Syötä luvut:"), kunnes käyttäjä antaa luvun -1. Kun käyttäjä syöttää luvun -1, ohjelma tulostaa "Kiitos ja näkemiin!" ja päättyy.
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin!
Laajenna edellistä ohjelmaa siten, että ohjelma ilmoittaa käyttäjän syöttämien lukujen summan. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11
Laajenna edellistä ohjelmaa siten, että ohjelma ilmoittaa myös käyttäjien antamien lukujen lukumäärän. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11 Lukuja: 3
Muuta edellistä ohjelmaa siten, ohjelma ilmoittaa lukujen keskiarvon. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11 Lukuja: 3 Keskiarvo: 3.666666666666
Laajenna edellistä ohjelmaa siten, että ohjelma ilmoittaa parillisten ja parittomien lukujen määrän. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11 Lukuja: 3 Keskiarvo: 3.666666666666 Parillisia: 2 Parittomia: 1
Edeltävissä tehtävissä tehtiin oikeastaan ainoastaan yksi ohjelma, mutta ohjelman rakentaminen tapahtui hyvin pienissä paloissa. Tämä on ehdottoman suositeltava tapa AINA kun ohjelmoit.
Eli kun teet ohjelmaa, oli se sitten harjoitustehtävä tai oma projektisi, kannattaa edetä hyvin pienissä paloissa. Älä koskaan yritä ratkaista koko ongelmaa kerralla. Aloita jollain helpolla asialla jonka tiedät varmasti osaavasi. Esim. edellisessä tehtäväsarjassa keskityttiin aluksi pelkästään siihen, että osataan pysäyttää ohjelma käyttäjän syöttäessä luvun -1. Kun yksi ohjelman osa on saatu toimimaan, voidaan siirtyä ratkaisemaan jotain seuraavaa varsinaisen ongelman osaongelmaa.
Osa kurssin tehtäviä on edellisten tapaan valmiiksi osiin pilkottuja. Usein osat pitää vielä pilkkoa ohjelmoinnin kannalta vieläkin pienempiin paloihin. Kannattaa tehdä siten, että suoritat ohjelman lähes jokaisen uuden koodirivin jälkeen. Tällöin varmistat, että ratkaisu on etenemässä haluttuun suuntaan.
Lisätietoa: toisto for-lauseen avulla
Edellä esitellyn while-toistolauseen lisäksi Javassa toiston voi hoitaa myös for-toistolauseen avulla. Varsinaisesti rupeamme käyttämään for:ia vasta hieman myöhemmin kurssilla, mutta jo tässä vaiheessa mainittakoon, että toistolause
int i = 0; while ( i < 10 ) { System.out.println( i ); i++; }
tehtäisiin for:in avulla seuraavasti:
for ( int i = 0; i < 10 ; i ++ ) { System.out.println( i ); }
eli for-komento sisältää samalla rivillä indeksimuuttujan alustuksen, toistoehton ja indeksimuuttujan kasvatuksen puolipistein eroteltuna. Voit unohtaa for:in olemassaolon toistaiseksi jos et halua sekoittaa päätäsi sen olemassaololla.
Olemme käyttäneet useita erilaisia komentoja Javassa: sijoitusta, laskutoimituksia, vertailuja, if:iä ja whileä. Ruudulle tulostaminen on tehty "komentoa" System.out.println()
käyttäen. Kahden luvun maksimi osataan laskea "komennolla" Math.max()
. Tuttuja ovat myös lukija.nextLine()
ja sen kanssa usein nähty Integer.parseInt()
.
Huomaamme, että jälkimmäinen joukko edellä lueteltuja komentoja poikkeaa if:istä ja while:stä ym. siinä, että komennon perässä on sulut ja joskus sulkujen sisällä komennolle annettava syöte. "Sulkuihin päättyvät" eivät oikeastaan olekaan komentoja vaan metodeja.
Teknisesti ottaen metodi tarkoittaa koodinpätkää, jota voi kutsua muualta ohjelmakoodista. Koodirivi System.out.println("olen metodille annettava parametri!")
siis tarkoittaa, että kutsutaan metodia, joka suorittaa ruudulle tulostamisen. Metodin suorituksen jälkeen palataan siihen kohtaa missä ennen metodikutsua oltiin menossa. Metodille suluissa annettua syötettä kutsutaan metodin parametriksi.
Parametrin lisäksi metodilla voi olla paluuarvo. Esim. tuttu koodinpätkä:
int luku = Integer.parseInt( lukija.nextLine() );
sisältää kaksi metodikutsua. Ensin kutsutaan sisempänä olevaa metodia lukija.nextLine
. Metodilla on paluuarvonaan käyttäjän syöttämä merkkijono. Seuraavaksi
kutsutaan metodia Integer.parseInt
. Metodikutsun parametrina on merkkijono jonka lukija.nextLine
:n kutsu palautti ja metodin paluuarvona on merkkijonoa vastaava kokonaisluku.
Metodin nimeen näyttää liittyvän piste, esim. lukija.nextLine()
. Oikeastaan tässä metodin nimi onkin pisteen oikeanpuoleinen osa, eli nextLine()
. Pisteen vasemmanpuoleinen osa, eli tässä lukija
kertoo kenen metodista on kyse.
Eli kyseessä on lukijan metodi nextLine. Opimme hiukan myöhemmin tarkemmin mistä tässä pisteen vasemmanpuoleisessa
osassa on kyse. Tarkka lukija tietysti huomaa, että System.out.println()
:ssa on "kaksi pistettä". Metodin nimi tässä
on println, ja System.out
on se kenen metodista on kyse. Karkeasti ottaen System.out
tarkoittaa koneen näyttöä.
Tähän mennessä käyttämämme metodit ovat kaikki olleet Javan valmiita metodeita. Nyt opettelemme tekemään omia metodeita.
Olemme tähän mennessä ohjelmoineet ohjelmamme siten, että kaikki tapahtuu yhdessä jatkumossa ja koodia luetaan ylhäältä alas.
Edellä mainittiin että "metodi tarkoittaa koodinpätkää, jota voi kutsua muualta ohjelmakoodista". Javan valmiita metodeja on käytetty jo oikeastaan ensimmäisestä ohjelmasta lähtien.
Javan valmiiden metodien käytön lisäksi ohjelmoija voi kirjoittaa itse metodeja joita sovellus kutsuu. Oikeastaan on hyvin poikkeuksellista jos ohjelmassa ei ole yhtään itse kirjoitettua metodia. Tästälähtien lähes jokainen kurssilla tehty ohjelma sisältääkin itsekirjoitettuja metodeja.
Ohjelmarunkoon metodit kirjoitetaan main:in aaltosulkeiden ulkopuolelle mutta kuitenkin "uloimmaisten" aaltosulkeiden sisäpuolelle, joko mainin ylä- tai alapuolelle
import java.util.Scanner; public class OhjelmaRunko { // omia metodeja tänne public static void main(String[] args) { Scanner lukija = new Scanner(System.in); // ohjelmakoodi } // omia metodeja tai tänne }
Luodaan metodi tervehdi
.
public static void tervehdi() { System.out.println("Terveiset metodimaailmasta!"); }
Ja asetetaan se metodeille kuuluvalle paikalle.
import java.util.Scanner; public class OhjelmaRunko { public static void main(String[] args) { Scanner lukija = new Scanner(System.in); // ohjelmakoodi } // omat metodit public static void tervehdi() { System.out.println("Terveiset metodimaailmasta!"); } }
Metodin määrittely sisältää kaksi osaa. Metodimäärittelyn ensimmäisellä rivillä on metodin nimi eli tervehdi. Nimen vasemmalla puolella tässä vaiheessa määreet public static void
. Metodin nimen sisältävän rivin alla on aaltosulkeilla erotettu koodilohko, jonka sisälle kirjoitetaan metodin koodi, eli ne komennot jotka metodia kutsuttaessa suoritetaan. Metodimme tervehdi
ei tee muuta kuin kirjoittaa rivillisen tekstiä ruudulle.
Itsekirjoitetun metodin kutsu on helppoa, kirjoitetaan metodin nimi ja perään sulut ja puolipiste. Seuraavassa main eli pääohjelma kutsuu metodia ensin kerran ja sen jälkeen useita kertoja.
import java.util.Scanner; public class OhjelmaRunko { public static void main(String[] args) { Scanner lukija = new Scanner(System.in); // ohjelmakoodi System.out.println("Kokeillaan pääsemmekö metodimaailmaan:"); tervehdi(); System.out.println("Näyttää siltä, kokeillaan vielä:"); tervehdi(); tervehdi(); tervehdi(); } // omat metodit public static void tervehdi() { System.out.println("Terveiset metodimaailmasta!"); } }
Ohjelman suoritus saa aikaan seuraavan tulosteen:
Kokeillaan pääsemmekö metodimaailmaan: Terveiset metodimaailmasta! Näyttää siltä, kokeillaan vielä: Terveiset metodimaailmasta! Terveiset metodimaailmasta! Terveiset metodimaailmasta!
Huomionarvoista tässä on koodin suoritusjärjestys. Koodin suoritus etenee siten, että pääohjelman -- eli main:in -- rivit suoritetaan ylhäältä alas yksi kerrallaan. Koodirivin ollessa metodikutsu, mennään suorittamaan metodin koodirivit, jonka jälkeen palataan kohtaan, josta metodin kutsu tapahtui. Tarkemmin ottaen metodikutsun jälkeiselle riville.
Jos ollaan tarkkoja on pääohjelma eli main itsekin metodi. Kun ohjelma käynnistyy, kutsuu käyttöjärjestelmä main:ia. Metodi main on siis ohjelman käynnistyspiste, jonka ylimmältä riviltä ohjelman suoritus lähtee liikkeelle. Ohjelman suoritus loppuu kun päädytään mainin loppuun.
Jatkossa kun esittelemme metodeja, emme erikseen mainitse että niiden täytyy sijaita omalla paikallaan. Metodia ei esimerkiksi voi määritellä toisen metodin sisällä.
Tee metodi tulostaTeksti
, joka tulostaa
tekstin "Alussa olivat suo, kuokka ja Java." sekä rivinvaihdon.
public static void main(String[] args) { tulostaTeksti(); } public static void tulostaTeksti() { // kirjoita koodia tähän }
Ohjelman tulostus:
Alussa olivat suo, kuokka ja Java.
Laajenna edellistä ohjelmaa siten, että pääohjelma kysyy käyttäjältä, montako kertaa teksti tulostetaan eli montako kertaa metodia kutsutaan.
public static void main(String[] args) { // kysy käyttäjältä, montako kertaa teksti tulostetaan // kutsu metodia tulostaTeksti while-komennon avulla useita kertoja } public static void tulostaTeksti() { // kirjoita koodia tähän }
Ohjelman tulostus:
Kuinka monta? 7 Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java.
huom: tulosta kehote Kuinka monta? omalle rivilleen!
Metodista saa huomattavasti monikäyttöisemmän antamalla sille parametreja. Parametrit ovat muuttujia, jotka määritellään metodin ylimmällä rivillä metodin nimen jälkeen olevien sulkujen sisällä. Kun metodia kutsutaan, sen parametreille annetaan arvot kutsuvaiheessa.
Seuraavassa esimerkissä määritellään parametrillinen metodi tervehdi
, jolla on String-tyyppinen parametri nimi
.
public static void tervehdi(String nimi) { System.out.println("Hei " + nimi + ", terveiset metodimaailmasta!"); }
Kutsutaan metodia tervehdi
siten, että parametrin nimi
arvoksi asetetaan ensimmäisellä kutsulla Matti
ja toisella kutsulla Arto
.
public static void main(String[] args) { tervehdi("Matti"); tervehdi("Arto"); }
Hei Matti, terveiset metodimaailmasta! Hei Arto, terveiset metodimaailmasta!
Aivan kuten kutsuttaessa Javan valmista System.out.println()
-metodia, voi oman metodin kutsussa parametrina käyttää monimutkaisempaa ilmausta:
public static void main(String[] args) { String nimi1 = "Antti"; String nimi2 = "Mikkola"; tervehdi( nimi1 + " " + nimi2 ); int ika = 24; tervehdi("Juhana " + ika + " vuotta"); }
Hei Antti Mikkola, terveiset metodimaailmasta! Hei Juhana 24 vuotta, terveiset metodimaailmasta!
Molemmissa tapauksissa metodilla on edelleen vain 1 parametri. Parametrin arvo lasketaan ennen metodin kutsumista. Ensimmäisessä tapauksessa parametrin arvo saadaan merkkijonokatenaationa nimi1 + " " + nimi2
joka siis on arvoltaan Antti Mikkola ja jälkimmäisessä tapauksessa merkkijonokatenaatiosta "Juhana " + ika + " vuotta"
.
Metodille voidaan määritellä useita parametreja. Tällöin metodin kutsussa parametrit annetaan samassa järjestyksessä.
public static void tervehdi(String nimi, String mistaTerveiset) { System.out.println("Hei " + nimi + ", terveiset " + mistaTerveiset); }
String kuka = "Matti"; String terveiset = "Kyröjoelta"; tervehdi(kuka, terveiset); tervehdi(kuka, terveiset + " ja Kumpulasta");
Jälkimmäisessä tervehdi
-funktion kutsussa toinen parametri muodostetaan katenoimalla muuttujaan terveiset
teksti " ja Kumpulasta"
. Tämä suoritetaan ennen varsinaista funktion suoritusta.
Hei Matti, terveiset Kyröjoelta Hei Matti, terveiset Kyröjoelta ja Kumpulasta
main ei ole suinkaan ainoa joka voi kutsua metodeita. Metodit voivat kutsua myös toisiaan. Tehdään metodi tervehdiMontaKertaa
, joka tervehtii käyttäjää useasti metodin tervehdi
avulla:
public static void tervehdi(String nimi) { System.out.println("Hei " + nimi + ", terveiset metodimaailmasta!"); } public static void tervehdiMontaKertaa(String nimi, int kerrat) { int i = 0; while ( i < kerrat ) { tervehdi(nimi); i++; } } public static void main(String[] args) { tervehdiMontaKertaa("Antti", 3); System.out.println("ja"); tervehdiMontaKertaa("Martin", 2); }
Tulostuu:
Hei Antti, terveiset metodimaailmasta! Hei Antti, terveiset metodimaailmasta! Hei Antti, terveiset metodimaailmasta! ja Hei Martin, terveiset metodimaailmasta! Hei Martin, terveiset metodimaailmasta!
Screencast aiheesta:
Tee metodi tulostaTahtia
,
joka tulostaa annetun määrän tähtiä ja rivinvaihdon.
Tee metodi seuraavaan runkoon:
private static void tulostaTahtia(int maara) { // yhden tähden saat tulostettua komennolla // System.out.print("*"); // kutsu tulostuskomentoa n kertaa // tulosta lopuksi rivinvaihto komennolla // System.out.println(""); } public static void main(String[] args) { tulostaTahtia(5); tulostaTahtia(3); tulostaTahtia(9); }
Ohjelman tulostus:
***** *** *********
huom: moniosaisen tehtävät voi palauttaa palvelimelle (painamalla testausnapin oikealla puolella olevaa nappia) vaikka kaikki osat eivät olisikaan tehty. Palvelin valittelee tällöin tekemättömien osien testeistä, tehdyt osat palvelin kirjaa.
Tee metodi tulostaNelio(int sivunpituus)
joka tulostaa neliön käyttäen tulostaTahtia
-metodia. Siis esimerkiksi kutsu tulostaNelio(4)
tulostaa seuraavaa:
**** **** **** ****
Huom: tehtävässä ei riitä että tulostus näyttää oikealta, tulostaNelio-metodin sisällä neliön "rivien" tulostus tulee tehdä tulostaTahtia-metodia käyttäen.
Ohjelmaa tehdessäsi kannattaa varmistaa main:iin kirjoitetun testikoodin avulla että metodit toimivat vaaditulla tavalla.
Tee metodi tulostaSuorakulmio(int leveys, int korkeus)
joka tulostaa suorakulmion käyttäen tulostaTahtia
-metodia. Siis esimerkiksi kutsu tulostaSuorakulmio(17,3)
tulostaa seuraavaa:
***************** ***************** *****************
Tee metodi tulostaKolmio(int koko)
joka tulostaa kolmion käyttäen tulostaTahtia
-metodia. Siis esimerkiksi kutsu tulostaKolmio(4)
tulostaa seuraavaa:
* ** *** ****
Tee metodi tulostaTyhjaa(int maara)
joka tulostaa maara
kappaletta välilyöntejä. Metodi ei tulosta rivinvaihtoa.
Joudut myös joko kopioimaan edellisen tehtävän vastauksestasi metodin tulostaTahtia
tai toteuttamaan sen uudelleen tämän tehtävän tehtäväpohjaan.
Tee metodi tulostaKolmio(int koko)
joka tulostaa kolmion käyttäen tulostaTyhjaa
- ja tulostaTahtia
-metodeja. Siis esimerkiksi kutsu tulostaKolmio(4)
tulostaa seuraavaa:
* ** *** ****
Tee metodi jouluKuusi(int korkeus)
joka tulostaa joulukuusen. Joulukuusi koostuu annetun korkuisesta kolmiosta ja jalasta. Jalka on kaksi tähteä korkea ja kolme tähteä leveä ja se on keskellä kolmion pohjaa.
Kuusi tulee rakentaa käyttämällä tulostukseen metodeja tulostaTyhjaa
ja tulostaTahtia
Esimerkiksi kutsu jouluKuusi(4)
tulostaa seuraavaa:
* *** ***** ******* *** ***
Kutsu jouluKuusi(10)
tulostaa:
* *** ***** ******* ********* *********** ************* *************** ***************** ******************* *** ***
Huom: Korkeuksien jotka ovat alle 3 ei tarvitse toimia!
Tässä tehtävässä luodaan seuraavanlainen numerovisa:
Arvaa luku: 73 Luku on pienempi, tehtyjä arvauksia: 1 Arvaa luku: 22 Luku on suurempi, tehtyjä arvauksia: 2 Arvaa luku: 51 Luku on suurempi, tehtyjä arvauksia: 3 Arvaa luku: 62 Luku on suurempi, tehtyjä arvauksia: 4 Arvaa luku: 68 Luku on suurempi, tehtyjä arvauksia: 5 Arvaa luku: 71 Luku on pienempi, tehtyjä arvauksia: 6 Arvaa luku: 70 Onneksi olkoon, oikein arvattu!
Tehtävänannon mukana tulevassa ohjelmassa tulee mukana komento arvoLuku
, joka arpoo luvun suljetulta väliltä [0, 100] (0 ja 100 ovat myös mahdollisia). Toteuta ohjelma jossa arvataan arvottua lukua kerran. Ohjelman tulee tulostaa joko "Luku on pienempi", "Luku on suurempi" tai "Onneksi olkoon, oikein arvattu!" riippuen käyttäjän antamasta luvusta.
Arvaa luku: 12 Luku on suurempi
Arvaa luku: 66 Luku on pienempi
Arvaa luku: 42 Onneksi olkoon, oikein arvattu!
Lisää ohjelmaan toiminnallisuus jossa arvausta tehdään toistuvasti kunnes käyttäjä syöttää oikean numeron. Huomaa, että sinun tulee arpoa numero komentoa arvoLuku
ennen toistolauseketta. Miksi? Mitä tapahtuu, jos luku arvotaan toistolausekkeen sisällä?
Alla olevassa esimerkissä kutsu komentoon arvoLuku
palautti arvon 83.
Arvaa luku: 55 Luku on suurempi Arvaa luku: 85 Luku on pienempi Arvaa luku: 77 Luku on suurempi Arvaa luku: 81 Luku on suurempi Arvaa luku: 83 Onneksi olkoon, oikein arvattu!
Lisää ohjelmaan kokonaislukutyyppinen muuttuja, jonka avulla pidetään kirjaa tehtyjen arvausten määrästä. Tulosta arvausten määrä aina arvauksen yhteydessä.
Arvaa luku: 55 Luku on suurempi, tehtyjä arvauksia: 1 Arvaa luku: 85 Luku on pienempi, tehtyjä arvauksia: 2 Arvaa luku: 77 Luku on suurempi, tehtyjä arvauksia: 3 Arvaa luku: 81 Luku on suurempi, tehtyjä arvauksia: 4 Arvaa luku: 83 Onneksi olkoon, oikein arvattu!
Käytämme tällä kertaa robottia viivataiteen luomiseen. Käytössä olevat komennot ovat Ohjain.kaynnista()
, Ohjain.sammuta()
, Ohjain.vasen()
, Ohjain.oikea()
ja Ohjain.liiku()
, joiden lisäksi yksittäisen askeleen odotusajan voi asettaa komennolla Ohjain.asetaOdotusaika(int millisekuntia)
.
Tämän tehtäväsarjan lopussa sinulla on koodi, jolla voit yhdellä metodikutsulla luoda esimerkiksi seuraavanlaisen kuvion.
Aloitetaan.
Toteuta metodi public static void liikuMonta(int montakoAskelta)
, joka siirtää robottia halutun määrän askelia siihen suuntaan, mihin robotti osoittaa. Esimerkiksi metodikutsu liikuMonta(5);
siirtää robottia siten, että lopputila on seuraavanlainen.
Toteuta metodi public static void piirraNelio(int sivunPituus)
, joka piirtää annetun kokoisen neliön (parametri sivunPituus kertoo yksittäisen sivun pituuden). Hyödynnä tässä edellisessä osassa tehtyä metodia liikuMonta
.
Metodikutsun piirraNelio(8);
tulee siirtää robottia siten, että lopputilanne on seuraavanlainen. Huomaa, että aina kun sivu on valmis, robotti kääntyy oikealle.
Toteuta seuraavaksi metodi public static void sisakkaisetNeliot(int montako)
, joka piirtää sisäkkäisiä neliöitä. Suurimman neliön sivun pituus on montako
-parametrille annettava arvo, ja pienimmän neliön sivun pituus on yksi.
Alla olevassa kuvassa metodia on kutsuttu parametrilla 10 (sisakkaisetNeliot(10);
)
Hyödynnä tässä aiemmin toteutettua metodia piirraNelio
.
Toteuta seuraavaksi metodi rajatutSisakkaisetNeliot(int suurin, int pienin);
sisäkkäisten neliöiden piirtämiseen. Tämä metodi saa parametrina kaksi arvoa, joista ensimmäinen kertoo suurimman piirrettävän neliön sivun pituuden, ja toinen kertoo pienimmän piirrettävän neliön sivun pituuden.
Alla olevassa kuvassa metodia on kutsuttu parametreilla 8 ja 4 (rajatutSisakkaisetNeliot(8, 4);
). Huom! Kuvassa on viisi neliötä (ja rho-botti, jota jotkut voisivat väittää neliöksi)!
Kun metodi rajatutSisakkaisetNeliot
toimii, muuta edellisessä tehtävässä olevan sisakkaisetNeliot
-metodin toimintaa siten, että se kutsuu tässä tehtävässä toteutettua metodia.
Viimeinkin!
Toteuta metodi public static void viivakimara(int koko)
, jonka avulla voit piirtää jonkun mielekkään kuvion (voit pyrkiä esimerkiksi alla olevaan kuvaan). Toteuta viivakimara siten, että kuvat ovat erilaisia eri parametrin koko arvoilla.
Eeppisimmät viivakimarat tulevat näkyville vielä nimeämättömään paikkaan.