Lisamaterjalid 8
Väärtustik (enum)
Oletame, et meil on menüü, kus saab valida aastaaega (suvi, sügis, kevad, talv). Kuna sellel on kindel hulk võimalikke väärtusi, mis ei muutu, oleks mõistlik kasutada konstante. Sellise hulga esindamiseks saab kasutada väärtustikku, mida Javas defineeritakse võtmesõna enum abil. See realiseerib klassi Enum
ja ei saa olla millegi muu ülemklass ega alamklass (v.a konstantide). Klassi Enum
tähtsamad meetodid on:
name
– tagastab konstandi nime. Eelistatud on kasutada meetoditoString
;valueOf
– võtab argumendiks sõne ja tagastab samanimelise konstandi, kui see eksisteerib;ordinal
– tagastab täisarvuna konstandi positsiooni.
Väärtustikus Ilmakaar
on konstantideks neli põhiilmakaart (põhi, lõuna, ida, lääs). Konstante kirjutatakse läbivalt suurte tähtedega ning vajadusel eraldatakse nimes sõnu alakriipsuga:
enum Ilmakaar { PÕHI, LÕUNA, IDA, LÄÄS }
System.out.println(Ilmakaar.IDA);
väljastab: IDA
Ilmakaar.IDA.name();
tagastab: IDA
Ilmakaar.valueOf("IDA");
tagastab: IDA
Ilmakaar.IDA.ordinal();
tagastab: 2
Väärtustiku kõikide konstantide läbikäimiseks saab kasutada meetodi values
:
for (Ilmakaar kaar: Ilmakaar.values()) { System.out.println(kaar); }
Väljastab:
PÕHI LÕUNA IDA LÄÄS
Konstantide võrreldakse operaatori ==
või meetodi equals
abil, aga selleks saab ka kasutada lülitidirektiivi, mida käsitleti seitsmenda nädala lisamaterjalides:
public static int kaarKraadiks(Ilmakaar kaar) { return switch (kaar) { case PÕHI -> 0; case LÕUNA -> 180; case IDA -> 90; case LÄÄS -> 270; }; }
kaarKraadiks(Ilmakaar.LÕUNA);
tagastab: 180
Väärtustikul IlmakaarTäiustatud
on konstruktor, final
isendiväli kraad ja selle get
-meetod, et väljendada sama informatsiooni, mida tagastas meetod kaarKraadiks
. Lisaks saab väärtustikul olla konstantidele realiseerimiseks abstraktseid meetodeid, nagu asimuut
.
enum IlmakaarTäiustatud { PÕHI(0) { public String asimuut() { return "Põhja asimuut on 0°"; } }, LÕUNA(180) { public String asimuut() { return "Lõuna asimuut on 180°"; } }, IDA(90) { public String asimuut() { return "Ida asimuut on 90°"; } }, LÄÄS(270) { public String asimuut() { return "Lääne asimuut on 270°"; } }; private final int kraad; IlmakaarTäiustatud(int kraad) { this.kraad = kraad; } public int getKraad() { return kraad; } public abstract String asimuut(); }
System.out.println(IlmakaarTäiustatud.LÄÄS);
väljastab: LÄÄS
IlmakaarTäiustatud.LÄÄS.getKraad();
tagastab: 270
IlmakaarTäiustatud.LÄÄS.asimuut();
tagastab: Lääne asimuut on 270°
Enesekontroll
Lambda-avaldised
Kuigi Java on objektorienteeritud, toetab see funktsionaalse programmeerimise kontseptsioone, kus on olulised lambdad. Lambda-avaldised on nimeta meetodid, mis aitavad realiseerida ühe abstraktse meetodiga liideseid ehk funktsiooniliideseid (functional interface). Abstraktne meetod määrab lambda parameetrite arvu, nende tüüpe ja tagastustüübi. Lambdad võimaldavad kasutada kõrgemat järku funktsioone olles meetodi argument või tagastus. Lisaks vähendavad need koodi pikkust. Funktsiooniliideseid saab ise kirjutada, aga neid leidub ka paketis java.util.function
. Selle paketi liidesed on kasutuses Stream API-s, millest räägime täpsemalt järgmisel nädalal.
Liidesel Ruut
on üks abstraktne meetod arvuta, millel on int
-tüüpi parameeter a
. Sellel on funktsiooniliidest tähistav annotatsioon @FunctionalInterface
, mis aitab kompilaatoril ja koodi lugejal vigu leida.
@FunctionalInterface interface Ruut { int arvuta(int a); }
Lambdasid kirjutatakse kujul (esimeneParameeter, teineParameeter, jne) -> avaldis, aga ühe parameetriga lambdas võib sulud ära jätta:
Ruut pindala = a -> a * a; pindala.arvuta(3);
Tagastab: 9
Lambdas saab välja tuua parameetrite tüüpe ja mitmerealises lambdas kasutatakse looksulge { }
:
Ruut kolm = (int a) -> { System.out.println("Tagastatakse number 3"); return 3; }; kolm.arvuta(10);
Tagastab 3
ja väljastab:
Tagastatakse number 3
Lambdal ei pea olema parameetreid ega tagastust:
@FunctionalInterface interface Sõnum { void väljasta(); }
Sõnum ruuduKüljed = () -> System.out.println("Ruudul on 4 külge"); ruuduKüljed.väljasta();
Väljastab:
Ruudul on 4 külge
Paketis java.util.function
asub geneerilist tüüpi parameeteriga funktsiooniliides Predicate
. Sellel on muuhulgas tõeväärtust tagastatav meetod test
ja erinevateks teheteks konjunktsioon and
, disjunktsioon or
ja eitus negate
. Loome predikaadi onPaaris
, mis kontrollib, kas arv on paaris:
Predicate<Integer> onPaaris = arv -> arv % 2 == 0;
onPaaris.test(2);
tagastab: true
onPaaris.test(1);
tagastab: false
onPaaris.negate().test(1);
tagastab: true
Loome uue predikaadi onPositiivne
ja ühendame selle eelnevaga meetodi and
abil:
Predicate<Integer> onPositiivne = arv -> arv > 0; Predicate<Integer> onPaarisJaPositiivne = onPaaris.and(onPositiivne);
Predikaat onPaarisJaPositiivne
on tõene ainult siis, kui arv on positiivne ja paaris:
onPaarisJaPositiivne.test(10);
tagastab: true
onPaarisJaPositiivne.test(3);
tagastab: false
onPaarisJaPositiivne.test(-2);
tagastab: false
onPaarisJaPositiivne.test(-5);
tagastab: false