Meetod (alamprogramm)


Java rakendus sisaldab põhiprogrammi (main), millest tõenäoliselt pöördutakse ka mingite alamprogrammide poole. Javas nimetatakse alamprogramme meetoditeks (tulenevalt selle keele objektorienteeritusest) ning meetodid on rühmitatud klasside kaupa. Meetodid võivad olla kas programmeerija enda poolt loodud või Javasse sisse ehitatud (nn. API meetodid, mille kirjelduse leiab Java dokumentatsioonist). Sõltumata sellest, kust meetod pärineb, võib see olla kas klassi- või isendimeetod.

Klassimeetod  (class method) , mida Javas kirjeldab võtmesõna static, on kasutatav n.ö. "igas olukorras", s.t. ei ole vajalik objektorienteeritud paradigma järgimine (esialgu püüame oma kursuses läbi ajada klassimeetoditega). Täpsemalt öeldes - klassimeetodi poole pöördumiseks ei ole vajalik objekti olemasolu.
Klassimeetodi poole pöördumiseks kirjutatakse reeglina:
Klassi_nimi . meetodi_nimi ( faktilised_parameetrid );
Kui meetod on defineeritud jooksvas klassis, siis võib klassi nime (ja punkti) ära jätta.

Näit.     Math.sqrt (2.);



Isendimeetod (instance method) on rakendatav mingile etteantud objektile (seda objekti tähistatakse meetodi kirjelduses võtmesõnaga this). Isendimeetodi rakendamist nim. ka teate saatmiseks objektile.
Isendimeetodi poole pöördumiseks kirjutatakse reeglina:
objekt . meetodi_nimi ( faktilised_parameetrid );
Kui isendimeetodi poole pöördumisel on objektiks this, siis võib selle (ja punkti) ära jätta.

Näit.     "Tere hommikust!" .length();



Meetodi poole pöördumine (method call)  toimub faktiliste e. tegelike parameetritega, s.t. meetodi nime järele kirjutatakse ümarsulgudesse sobivat tüüpi avaldised. Kui parameetrite arv on null, siis tuleb Javas ikkagi kirjutada tühjad sulud (et eristada meetodit muutujast).

Meetodi defineerimisel kasutame formaalseid parameetreid, mis seatakse tegelike parameetritega vastavusse meetodi poole pöördumisel. Javas seostatakse parameetrid positsiooni järgi, s.t. oluline on täpne parameetrite järjestus. Ka võtmesõna this võib käsitleda formaalse parameetrina, millele vastab pöördumisel punkti ees olev objekt.
Lisaks sellele määratakse meetodi defineerimisel alati nn. tagastustüüp (s.t. mis tüüpi väärtus on meetodi töö tulemuseks). Tagastusväärtuse puudumisel on tagastustüübiks void. Tagastusväärtuse määrab meetodis täidetava return-lause järel olev avaldis (void-meetoditel on return-lause ilma avaldiseta).

Sisendparameetrid on meetodile algandmeteks, mida ei muudeta. Väljundparameetrid (Java korral on ainsaks väljundparameetriks tagastusväärtus) on meetodi töö tulemuseks. Sisend-väljundparameetrid on korraga mõlemas rollis (s.t. neid muudetakse meetodi töö käigus), olles Javas siiski süntaktiliselt samaväärsed sisendparameetritega.

Kui meetod ei tegele sisendi/väljundiga ning ei muuda keskkonna seisu kaudselt (näiteks muutes parameetrite kaudu kättesaadavaid objekte), siis nim. seda kõrvalefektideta meetodiks.


Meetodi    signatuuriks on meetodi nimi, parameetrite tüübid ja tagastusväärtuse tüüp.



Näide:

Klassimeetodid: main, syt
Formaalsed parameetrid: main-meetodi korral param,    syt korral a ja b
Faktilised parameetrid: syt korral m ja n
Tagastusväärtus: a

public class Euclid {

   public static void main (String[] param) {
      int m=15;
      int n=6;
      if (param.length > 1) {
         m=Integer.parseInt (param [0]);
         n=Integer.parseInt (param [1]);
      }
      System.out.println ("SYT (" + m + ", " + n
         + ") = " + syt (m, n));

   } // main

   public static int syt (int a, int b) {
      while (b != 0) {
         int j22k = a % b;
         a = b;
         b = j22k;
      }
      return a;
   } // syt

} // Euclid



Massiiv


Kui muutujaid on vähe, siis pole ka probleemi neile nimede leidmisega. Näiteks ruutvõrrandi lahendamise programmis leidsime kaks lahendit ja võisime neid nimetada x1 ja x2.  Kui peaksime aga arvutama 1000 väärtust mingi rutiinse reegli järgi, siis oleks väga ebamugav kirjeldada 1000 eraldi muutujat.  Ka tavaelus oleks raske linnas orienteeruda, kui majad poleks tänavate kaupa nummerdatud, vaid igal neist oleks oma nimi (isegi Inglismaal hakatakse sellest aru saama). Seda nummerdamise ideed kannab programmeerimises massiivi mõiste.

Massiiv on andmestruktuur, mis lubab samatüübilisi andmeid koondada ühise nime alla ning teha andmeelementidel vahet järjekorranumbri (indeksi) järgi. Üldisemal juhul võib indekseid olla rohkem kui üks - nii saadakse mitmemõõtmelised massiivid. Mitmemõõtmelist massiivi saab käsitleda kui massiivi, mille elementideks on omakorda massiivid (Javas ka nii tehakse).
Ühemõõtmelist (ühe indeksiga) massiivi nim. ka järjendiks, kahemõõtmelist massiivi maatriksiks või tabeliks.

Massiivi iseloomustavad seega:
  1. massiivi nimi (täpsemalt massiivi identifitseeriv L-väärtus)
  2. massiivi elemendi tüüp
  3. massiivi indeksite arv ja indeksite tüübid
  4. massiivi elementide arv (täpsemalt iga indeksi võimalike väärtuste hulk)
  5. massiivi elementide väärtused
Javas käsitletakse massiive ühemõõtmelistena, kahemõõtmeline massiiv on ühemõõtmeliste massiivide massiiv jne.
Javas on massiivi indeksiks täisarv vahemikus 0 kuni massiivi pikkus miinus üks.
Massiiv on massiivitüüpi muutuja (L-väärtus). Javas saab massiivi kirjeldada ilma massiivi elementide arvu fikseerimata. Elementide arv määratakse mälu reserveerimise käigus (see operatsioon on Javas massiivi kirjeldusest lahutatud).
Javas kasutatakse massiivi elemendile viitamiseks indeksit, mis kirjutatakse massiivi nime järele kantsulgudesse. Massiivi element on näide L-väärtusest, s.t. massiivi elemendile saab omistada väärtust.
Massiivi elementide arvu Javas (massiivi pikkust) väljendab Javas avaldis "massiivi_nimi .length" (massiiv on objekt, mille avalik read-only isendimuutuja nimega length sisaldab massiivi pikkust).


Näide.


      int [] m;                       // massiivi kirjeldamine

      m = new int [10];               // mälu reserveerimine massiivile

      System.out.println (m.length);  // massiivi pikkuse väljastamine

      m[0] = 3;                       // omistamine elemendile indeksiga 0
      m[1] = -8;

      // massiivi väljastamine for-tsükli abil
      for (int i=0; i<m.length; i++)
         System.out.print (String.valueOf (m[i]) + " ");
      System.out.println();
  


Massiivi kirjeldamist, mälu eraldamist ja massiivi elementide väärtustamist saab Javas teha korraga nn. massiivialgati abil.

int [] a = {3, -8, 0, 0, -1, 0, 0};


Luuakse 7-elemendiline täisarvude massiiv loetletud väärtustest ( a[0]==3, a[1]==-8, ..., a[6]==0 ).

Seda saab  kirjutada ka massiivitüüpi avaldisena:
new int [] {3, -8, 0, 0, -1, 0, 0}

Vt. joonist


Javas saab mitmemõõtmelise massiivi korral iga ülemisel tasemel kirjeldatud massiivi element olla erineva pikkusega massiiv.

Näide.

        int [][] m;                       // massiivi kirjeldamine
      m = new int [2][];                // mälu reserveerimine esimesel tasemel
      System.out.println (m.length);    // massiivi pikkus (esimene tase)
      m[0] = new int [4];               // mälu rerveerim. teisel tasemel
      m[0][0] = -8;                     // omistamine elemendile
      m[1] = new int [3];
      m[1][0] = 9;

      // massiivi v2ljastamine for-tsyklite abil
      for (int i=0; i<m.length; i++) {
         for (int j=0; j<m[i].length; j++)
            System.out.print (String.valueOf (m[i][j]) + " ");
         System.out.println();
      } // for i


Vt. joonist

Järjendi töötlemine

Vaatleme näiteülesandeid tööks ühemõõtmelise massiiviga.

Maksimumi leidmine

   public static int maks (int[] m) {
      int res = Integer.MIN_VALUE;
      for (int i=0; i<m.length; i++) {
         if (m[i] > res)
            res = m[i];
      } // for i
      return res;
   } // maks

Vastupidise elementide järjekorraga massiivi leidmine

   public static int [] reverse (int [] m) {
      int[] res = new int [m.length];
      for (int i=0; i<m.length; i++) {
         res [res.length - 1 - i] = m [i];
      }
      return res;
   } // reverse


Märgimuutude arvu leidmine


   public static int mmArv (int [] m) {
      int res = 0;
      if (m.length < 2) return 0;
      for (int i=0; i<m.length-1; i++) {
         if (m[i]>=0 && m[i+1]<0) res++;
         if (m[i]<0 && m[i+1]>=0) res++;
      }
      return res;
   } // mmArv


Muutuva parameetrite arvuga meetodi kirjeldamine Javas

Alates Java 1.5 saab meetodi parameetreid "pakkida" massiiviks, vt. näide:

import java.util.*;

public class Proov {

   public static void main (String[] args) {
      mm ("tere", "kaunis", "hommik");
   }

   public static void mm (String ... s) {
      System.out.println (s.length + " " + Arrays.toString(s));
   }

}




Jaanus Pöial