ALOITTELIJAN JAVA-OPAS


Esimerkkejä

Tässä luvussa esitetään muutamia kokonaisia esimerkkiohjelmia oppaan aihepiiristä. Ohjelmien toiminta on selostettu ennen varsinaista koodia ja koodi on kommentoitu ymmärtämisen helpottamiseksi. Voit kokeilla ohjelmia liitteiden alussa mainittujen ohjeiden avulla.

Esimerkki 1. Kuplalajittelu

Lukuja sisältävän taulukon lajittelu nousevaan järjestykseen on klassinen algoritmisesti ratkaistava tietojenkäsittelytieteen ongelma. Lajittelua varten on olemassa lukuisia algoritmeja, joista eräs on kuplalajittelu. Se on yksinkertainen, mutta melko hidas tapa suorittaa lajittelu. Ideana on järjestää taulukko vertailemalla taulukon kahta vierekkäistä arvoa; jos ensimmäinen arvo on toista pienempi, niiden paikat vaihdetaan. Tällä tavalla käydään läpi kaikki taulukon lukuparit, ja vaihtojen seurauksena suurin taulukossa oleva arvo siirtyy tai "kuplii" taulukossa taaksepäin ja päätyy lopulta taulukon viimeiseksi arvoksi. Silloin läpikäynti aloitetaan jälleen alusta, jolloin taulukon toiseksi suurin arvo päätyy toiseksi viimeiseksi. Toistoa jatketaan, kunnes kaikki arvot on lajiteltu. Visuaalinen esitys lajittelun toiminnasta on nähtävissä osoitteessa http://www.cs.princeton.edu/~ah/alg_anim/gawain-4.0/BubbleSort.html.

Tässä esimerkissä on neljä osaa: pääohjelma ja metodit taulukon luomiseen, lajitteluun ja tulostamiseen. Kaikki esimerkin metodit ovat staattisia, eli Javan oliopiirteitä käytetä, vaan metodit toimivat pääohjelman "apulaisina" (kuten "perinteisissä" ohjelmointikielissä). Sen sijaan taulukko johon luvut tallennetaan on olio; tämä näkyy lähinnä siinä miten taulukko luodaan. Tiedon lukemiseen käytetään erillistä Lue.java-luokkaa, joka sisältää valmiina pakettina tiedon lukemiseen liittyviä metodeja. Lue.java kopioidaan hakemistoon jossa myös tiedosto KuplaLajittelu.java sijaitsee, jolloin se käännetään automaattisesti yhdessä pääohjelman kanssa komennolla javac KuplaLajittelu.java. Lue.java löytyy esim. osoitteesta http://www.cs.helsinki.fi/u/wikla/JohdOhj/Sisalto/2/Lue.java. Kääntämisen jälkeen ohjelma pyytää syöttämään viisi lukua yksi kerrallaan. Kun luvut on syötetty, ohjelma tulostaa ne lajiteltuina.


	//--------------------------------------------------------------------------------

	// Esimerkin runko on peräisin teoksesta:

	// Arto Wikla: Ohjelmoinnin perusteet Java-kielellä, OtaDATA 1998

	// kappale 2.8.4, s. 79

	//

	// Tätä opasta varten alkuperäiseen esimerkkiin on lisätty kommentointia 

	// sekä erilliset metodit taulukon luomiseen (Lue-luokan avulla) ja tulostamiseen

	//--------------------------------------------------------------------------------

	

	

	public class KuplaLajittelu { // Luokan määrittely

	//Luokka sisältää metodit yksinkertaisen kuplalajittelun suorittamiseksi

	

	

	  static int taulukon_koko=5; //Määritellään taulukon koko vakiona

	

	  /**

	   *Metodi luo taulukon, lukee siihen asetettavat luvut ja palauttaa tuloksen

	   *pääohjelmalle

	   **/

	  private static int[] luoTaulu(){

	  

	    int[] a=new int[taulukon_koko]; //Luodaan halutun suuruinen taulukko(-olio)

	    int i=0;                        //Alustetaan laskurimuuttuja

	  

	    System.out.println("Anna "+taulukon_koko+" kokonaislukua:");

	  

	    //Silmukka:luetaan lukuja ja sijoitetaan ne taulukkoon, kunnes se on täynnä

	    while(i < taulukon_koko) {    

	      a[i]=Lue.kluku();     //Luettu arvo taulukkoon

	      i++;                  //Laskurin kasvatus

	    }

	  

	    return a;               //Palautetaan luotu taulukko

	    

	  } 

	

	   

	  /**

	   *Metodi tulostaa parametrina saamansa taulukon sisällön for-silmukan avulla

	   **/

	  private static void tulostaTaulu(int[] a){

	   

	    for (int i=0; i < a.length; ++i)   

	      System.out.print(a[i]+" ");  //Tulostus solu kerrallaan

	    System.out.println();

	  

	  }

	

	

	  /**

	   *Metodi lajittelee parametrina saamansa taulukon nousevaan järjestykseen.

	   **/

	  private static void kuplaLajittele(int[] taulu) {

	   

	    //Sisäkkäiset for-silmukat, joiden avulla taulukkoa käydään läpi

	    for (int i=taulu.length; i > 0; --i)  //Läpikäyntien määrä

	      for (int j=0; j < i-1; ++j)         //Taulukon läpikäynti kerran

	        if (taulu[j] > taulu[j+1]){       //jos järjestys väärä,

	          int apu = taulu[j];      //siirretään isompi arvo apumuuttujaan

	          taulu[j] = taulu[j+1];   //siirretään pienempi isomman paikalle  

	          taulu[j+1] = apu;        //ja isompi apumuuttujasta pienemmän päälle

	        }

	   

	  }

	  

	

	  /**

	   *Pääohjelma luo lajiteltavan taulukon, tulostaa ja järjestää sen, 

	   *ja tulostaa lopuksi järjestetyn taulukon luokan metodien avulla.

	   **/  

	  public static void main(String[] args) { //Pääohjelma

	  

	    int[] a = luoTaulu();  //Luodaan taulukko a

	    System.out.println("Annoit seuraavat luvut:");

	    tulostaTaulu(a);

	    System.out.println("Antamasi luvut järjestettynä:");

	    kuplaLajittele(a);

	    tulostaTaulu(a);

	  

	  } //Pääohjelman loppu

	

	  

	} //Luokan loppu




Esimerkki 2. Suorakulmio

Tämä esimerkki esittelee Javan käyttöä varsinaisessa olio-ohjelmoinnissa. Luokka Suorakulmio sisältää toiminnot erilaisten suorakulmio-olioiden luomiseen ja käsittelyyn. Suorakulmio määritellään vasemman alakulman ja oikean yläkulman koordinaattien avulla. Luokan metodien avulla luotuja suorakulmio-olioita voidaan käsitellä monin tavoin: toimintoihin kuuluvat koordinaattien tulostaminen, alan laskeminen, siirtäminen, pisteen sijainnin testaaminen suorakulmioon nähden ja kahden suorakulmion yhdisteen laskeminen.




	// Esimerkki kirjasta _Java Examples in a Nutshell_. (http://www.oreilly.com)

	// Copyright (c) 1997 by David Flanagan

	// Tätä opasta varten esimerkki on käännetty suomeksi, lisätty

	// kommentteja ja muunneltu jonkin verran 

	

	

	/**

	 *Luokka suorakulmioiden käsittelyyn. Kokonaislukukentät tarkoittavat 

	 *vasemman ala- ja oikean yläkulman koordinaatteja. Metodit ovat erilaisia   

	 *toimintoja, joita suorakulmioille voi tehdä. Luokka hyväksyy myös viivat ja

	 *pisteet, joiden ala on nolla.

	 **/

	public class Suorakulmio {

	

	

	  //Suorakulmion vasemman alakulman ja oikean yläkulman koordinaatit

	  private int x1, y1, x2, y2;	

	

	

	  /**

	   *Luokan pääkonstruktori, jonka avulla suorakulmio-olio luodaan. Parametreina

	   *konstruktorille välitetään vasemman ylä- ja oikean alakulman koordinaatit. 

	   **/

	  public Suorakulmio(int x1, int y1, int x2, int y2) {

	  

	    this.x1 = x1;   //this-määreellä parametrina saatu arvo sijoitetaan 

	    this.y1 = y1;   //luotavan suorakulmio-olion "ominaisuudeksi"

	    this.x2 = x2;

	    this.y2 = y2;

	    

	  }

	

	  

	  /**

	   *Vaihtoehtoinen (kuormitettu) konstruktori. Kun suorakulmio halutaan

	   *luoda antamalla vain leveys ja korkeus, kutsu välittyy tälle 

	   *konstruktorille, joka kutsuu luokan pääkonstruktoria. Tällöin suorakulmion 

	   *vasemman alakulman sijainniksi tulee koordinaatiston keskipiste.

	   **/

	  public Suorakulmio(int leveys, int korkeus) { 

	  

	    this(0, 0, leveys, korkeus); 

	    

	  }

	

	  

	  /**Jos suorakulmio halutaan luoda ilman mitään parametreja, kutsu välittyy

	   *tälle konstruktorille, joka puolestaan kutsuu pääkonstruktoria luoden 

	   *suorakulmio-olion joka on pelkkä origossa oleva piste.

	   **/

	  public Suorakulmio() { 

	  

	    this(0, 0, 0, 0); 

	    

	  }

	



	  /*Aksessorit, joilla suorakulmioita voidaan käsitellä muista 

	   *metodeista käsin.*/

	

	

	  /**Näillä saadaan tiedot koordinaateista*/

	  public int annaX1(){return this.x1;}

	  public int annaY1(){return this.y1;}

	  public int annaX2(){return this.x2;}

	  public int annaY2(){return this.y2;}

	

	  

	  /**Metodi palauttaa suorakulmion pinta-alan*/

	  public int annaAla(){

	  

	    return (x2-x1)*(y2-y1);

	

	  } 

	  

	  

	  /** Siirtää suorakulmiota annetun määrän*/

	  public void siirra(int deltax, int deltay) {

	  

	    x1 += deltax;   //x1=x1+deltax

	    x2 += deltax;

	    y1 += deltay; 

	    y2 += deltay;

	

	  }

	

	

	  /** Testaa onko annettu piste suorakulmion sisällä*/

	  public boolean onSisalla(int x, int y) {

	  

	    return ((x >= x1) && (x <= x2) && (y >= y1) && (y <= y2));

	

	  }

	

	  

	  /** 

	   *Palauttaa yhdistesuorakulmion ts. pienimmän sellaisen suorakulmion joka

	   *sisältää molemmat annetut suorakulmiot

	   **/

	  public Suorakulmio yhdiste(Suorakulmio s) {

	   

	    int ax,ay,bx,by; //Apumuuttujia

	    

	    //Määritetään yhdistesuorakulmion nurkat; vas. alakulman koordinaateiksi 

	    //tulevat yhdistettävien suorakulmioiden vasempien alakulmien pienimmät

	    //arvot ja yläkulman koordinaateiksi yhdistettävien suorakulmioiden 

	    //oikeiden ylänurkkien suurimmat arvot.

	

	    if (this.x1 < s.x1) ax=this.x1; else ax=s.x1;

	    //Tämän voi kirjoittaa lyhemmin: ax=(this.x1 < r.x1) ? this.x1 : r.x1;

	

	    if (this.y1 < s.y1) ay=this.y1; else ay=s.y1;

	    if (this.x2 > s.x2) bx=this.x2; else bx=s.x2;    

	    if (this.y2 > s.y2) by=this.y2; else by=s.y2;

	    

	    //Luodaan laskettujen koordinaattien mukaan uusi suorakulmio ja palautetaan se

	    return new Suorakulmio(ax,ay,bx,by);  

	    

	  }

	  

	  

	  /**

	   *Metodi jolla suorakulmio-olion tiedot voidaan tulostaa helposti; kun

	   *suorakulmioon viitataan kuin se olisi merkkijono, tulostuu tässä 

	   *metodissa määritelty String-lause.

	   **/

	  public String toString() {

	  

	    return "["+this.x1+","+this.y1+"; "+this.x2+","+this.y2+"]";

	

	  }

	

	

	} //Luokan loppu



	

Olioluokkaa ei yleensä suoriteta sellaisenaan, vaan on ohjelmoidaan erillinen pääohjelmaluokka, joka käyttää sitä. Seuraava luokka on laadittu tätä tarkoitusta varten, eli se testaa Suorakulmio-luokan eri toimintoja tulostaa saadut tulokset.




	// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com)

	// Copyright (c) 1997 by David Flanagan

	// Tätä opasta varten esimerkki on käännetty suomeksi, lisätty

	// kommentteja ja muunneltu jonkin verran

	

	/**Luokka esittelee Suorakulmio-luokan käyttöä*/

	public class SuorakulmioTesti {

	  

	  /**

	   *Pääohjelma  

	   **/

	  public static void main(String[] args) {

	  

	    //Luodaan 2 Suorakulmio-oliota eri konstruktoreilla  

	    Suorakulmio s1 = new Suorakulmio(0, 2, 4, 3); //0,2,4,3

	    Suorakulmio s2 = new Suorakulmio(3,3); //Annetaan vain leveys ja korkeus

	

	    //Testataan tulostusta toString()-metodin avulla ja aksessoreja

	    System.out.println("Suorakulmion s1 = "+s1+" vasen alakulma on pisteessä ("

	      +s1.annaX1()+","+s1.annaY1()+") ja oikea yläkulma pisteessä ("

	      +s1.annaX2()+","+s1.annaY2()+")");

		  

	    System.out.println("Suorakulmion s2 = "+s2+" vasen alakulma on pisteessä ("

	      +s2.annaX1()+","+s2.annaY1()+") ja oikea yläkulma pisteessä ("

	      +s2.annaX2()+","+s2.annaY2()+")");

	

	    //Testataan pinta-alan laskentaa; 

	    System.out.println("Suorakulmion s1 ala on "+s1.annaAla());

	    System.out.println("Suorakulmion s2 ala on "+s2.annaAla());

	

	    //Siirretään s2 pisteeseen (1,1) 

	    s2.siirra(1,1);

	    System.out.println("Suorakulmio s2 on nyt siirtynyt: s2 = "+s2);

	 

	    //Testataan onko piste (2,2) s1:n sisällä

	    if (s1.onSisalla(2,2))      

	      System.out.println("Piste (2,2) on suorakulmion s2 = "+s2+" sisällä");

	    else System.out.println("Piste (2,2) ei ole suorakulmion s2 = "+s2+" sisällä");

	    

	    //Testataan yhdistettä 

	    Suorakulmio yhd = s1.yhdiste(s2);  

	    System.out.println(s1 + " yhdiste " + s2 + " = " + yhd); 

	

	  }

	  

	} //Luokan loppu




Esimerkki 3. Palindromi

Tämä esimerkki osoittaa, miten näppärästi tekstidataa voi käsitellä Javalla String- ja StringBuffer-luokkien metodien avulla. Palindomithan ovat sellaisia tekstinpätkiä, jotka ovat samoja molemmin päin luettuina. Tämä esimerkkiohjelma testaa onko tietty tekstinpätkä palindromi vai ei. Kuten esimerkki 1, tämäkin esimerkki sisältää vain staattisia metodeja. Samoin tämäkin esimerkki vaatii Lue.java-apuluokan: http://www.cs.helsinki.fi/u/wikla/JohdOhj/Sisalto/2/Lue.java.

Ohjelma toimii silmukassa, jossa käyttäjää pyydetään syöttämään tekstiä. Ohjelma tutkii apumetodien avulla onko syöte palindromi ja ilmoittaa tekstin tuloksen. Vain merkkijonon kirjainmerkit huomioidaan, eli pilkut ym. syötetyt välimerkit eivät vaikuta tulokseen. Ilmoitettuaan tuloksen ohjelma kysyy haluaako käyttäjä jatkaa; jos vastaus on kyllä, silmukka suoritetaan uudelleen.




	

	//Luokka palindromien testaamiseen

	//Alkuperäinen koodi peräisin Sun-yhtiön web-sivulta,

	//http://java.sun.com/developer/codesamples/ 

	//Tätä opasta varten koodia hieman muunneltu, suomennettu ja lisätty kommentteja

	

	/**

	 *Luokka testaa onko tekstinpätkä palindromi.

	 *Muut kuin kirjainmerkit eivät vaikuta testin tulokseen.

	 **/

	public class Palindromi {

	

	  /**

	   *Metodi saa parametrina tekstinä ja palauttaa totuusarvona 

	   *palindromi-testin tuloksen, joka saadaan selville luokan muiden 

	   *metodien avulla

	   **/

	  public static boolean onPalindromi(String testattava) {

	  

	    //Poistetaan muut kuin kirjainmerkit apumetodin avulla

	    String vain_kirjaimet = poistaTurhat(testattava);

	

	    //Käännetään saatu tulos toisinpäin apumetodin avulla

	    String kaannettyKopio = kaanna(vain_kirjaimet);

	

	    //Jos vain kirjaimet sisältävä tekstinpätkä ei muuttunut toisinpäin 

	    //käännettäessä, palautetaan true, muulloin false. Tulokseen ei vaikuta,

	    //ovatko kirjaimet isoja vai pieniä (IgnoreCase).

	    return kaannettyKopio.equalsIgnoreCase(vain_kirjaimet);

	

	  }

	

	

	  /**

	   *Metodi poistaa tekstinpätkästä merkit jotka eivät ole kirjaimia

	   **/

	  protected static String poistaTurhat(String teksti) {

	

	    int i;  //Laskurimuuttuja

	    int pituus = teksti.length(); //Määritetään tekstinpätkän merkkien määrä

		

	    //Luodaan pituudeltaan String-parametria vastaava Stringbuffer-olio

	    StringBuffer tulos = new StringBuffer(pituus);  

	

	    char c; //Apumerkki

	

	    //Käydään string-parametrin merkit läpi for-silmukassa

	    for (i = (pituus - 1); i >= 0; i--) {

	

	      c = teksti.charAt(i);	//Otetaan merkki talteen

	      

	      //Jos merkki on kirjain, lisätään se StringBuffer-olioon

	      if (Character.isLetterOrDigit(c)) tulos.append(c);

	 

	    }

	

	    //Palautetaan Stringiksi muutettu vain kirjainmerkkejä sisältävä SringBuffer

	    //toString-metodi muuntaa Stringin StringBufferiksi

	    return tulos.toString(); 

	

	  }

	

	

	

	  /**

	   *Metodi kääntää parametrina saamansa tekstinpätkän nurinpäin ja palauttaa sen

	   **/

	  protected static String kaanna(String teksti) {

	

	    //Muunnetaan String-olio StringBuffer-olioksi

	    StringBuffer sb = new StringBuffer(teksti);

	    

	    //Käytetään kääntämiseen StringBuffer-luokan reverse-metodia, jolla

	    //saatu tulos palautetaan String-muodossa 

	    return sb.reverse().toString();

	  }

	

	

	  /**

	   *Pääohjelma; luodaan testattava teksti ja tulostukset

	   **/

	  public static void main(String[] args) {

	

	    char vastaus; //Silmukan testausmuuttuja

	

	    do{ //do-while-silmukan alku

	

	      //Kysytään testattava palindromi-ehdokas

	      System.out.println("Anna tekstiä, testaan onko se palindromi.");

	      String teksti = Lue.rivi();



	      //Jos onPalindromi palauttaa true-arvon, ehdokas on palindromi; 

	      //muulloin palautuu false

	      if (onPalindromi(teksti)) System.out.println("Se ON palindromi!");

	      else System.out.println("Se EI ole palindromi!"); 

	

	      System.out.println("Otetaanko uusiksi (k/e)?");

	      vastaus=Lue.merkki();

	

	    } while(vastaus=='k' || vastaus=='K'); //Silmukan jatkon tarkistus

	  }

	

	} //Luokan loppu


Tietojärjestelmien dokumentointi 2005 | Aloittelijan JAVA-opas


Valid CSS!