Lisamaterjalid 11
Veel kogumeid
Javas kuulub kogumitesse mitukümmend klassi ja veel suur hulk liideseid. Ajaga on neid muudetud ja juurde tulnud. Näiteks Java SE 21-s lisati uued liidesed SequencedCollection, SequencedSet ja SequencedMap, et paremini märkida kindlalt järjestatud kogumeid. Praegu keskendume neid otseselt või kaudselt realiseerivatele klassidele. Kogumite hierarhia on välja toodud kahel joonisel, kus on helesinised liidesed, sinised abstraktsed klassid ja lillad mitteabstraktsed klassid. Selles materjalis käsitletavad klassid on märgitud roosa äärega ja katkendlik nool tähistab, et mitteabstraktne klass realiseerib liidest.


LinkedHashSet ja LinkedHashMap
Klasside HashSet ja HashMap elementide järjestus pole kindel. Seda määrab erinevalt listist suuresti meetod hashCode, mitte elementide lisamise järjekord. Näiteks sisestades tühja HashSet-i arvud 7, 30, 15, 2 väljastatakse need järjekorras 2, 7, 30, 15. Sama loogika kehtib ka HashMap-iga.
Kui elementide lisamise järjekord on oluline programmi tööks, saab kasutada vastavalt klasse LinkedHashSet ja
LinkedHashMap. LinkedHashSet realiseerib liidest SequencedSet, millest tuleneb paar uut meetodit:
getFirst,getLast– tagastab esimese või viimase elemendi;removeFirst,removeLast– eemaldab ja tagastab esimese või viimase elemendi. Tühja hulga korral viskab erindiNoSuchElementException;addFirst,addLast– lisab hulga algusesse või lõppu elemendi;reversed– tagastab tagurpidi järjestatud hulga.
Klass LinkedHashMap realiseerib liidest
SequencedMap, mille meetodid sarnanevad üleval olevatega:
firstEntry,lastEntry– tagastab esimese või viimase elemendi;pollFirstEntry,pollLastEntry– eemaldab ja tagastab esimese või viimase elemendi;putFirst,putLast– lisab kujutuse algusesse või lõppu elemendi;reversed– tagastab tagurpidi järjestatud kujutuse.
Mõlemad kogumid väljastavad elemente lisamise järjekorras:
LinkedHashSet<String> linnad = new LinkedHashSet<>();
linnad.add("Tartu");
linnad.add("Tallinn");
linnad.add("Haapsalu");
System.out.println(linnad);
LinkedHashMap<String, Integer> riigid = new LinkedHashMap<>();
riigid.put("Eesti", 45335);
riigid.put("Läti", 64589);
riigid.put("Leedu", 65284);
System.out.println(riigid);
Väljastab:
[Tartu, Tallinn, Haapsalu]
{Eesti=45335, Läti=64589, Leedu=65284}
TreeSet ja TreeMap
Listi sorteerimiseks eksisteerib meetod Collections.sort. Hulkade ja kujutuste sorteerimiseks kasutatakse klasse
TreeSet ja TreeMap, mis hoiavad elemente alati õigesti järjestatult. Sorteerimine toimub nagu listilgi liidese Comparable või Comparator alusel.
Sorteerivad hulgad ja kujutused realiseerivad vastavalt liidest
NavigableSet või
NavigableMap, mis jõuavad välja samade liidesteni, mida kasutavad klassid LinkedHashSet ja LinkedHashMap. Selle tõttu realiseerivad need ka samu meetodeid. Kuigi esimese ja viimase elemendi lisamise meetodid viskavad erindi UnsupportedOperationException, sest elementide järjekorra määrab kogum ise. Siiski on mõned meetodid uued. Klassil TreeSet on nendeks:
first,last– tagastab esimese või viimase elemendi. Tühja hulga korral viskab erindiNoSuchElementException;pollFirst,pollLast– eemaldab ja tagastab esimese või viimase elemendi. Tühja hulga korral tagastabnull;lower,higher– tagastab võimalikult lähedase elemendi, mis on rangelt väiksem või suurem kui argument;floor,ceiling– tagastab argumendiga sama väärtust omava elemendi või sellele võimalikult lähedase elemendi, mis on väiksem või suurem argumendist;subSet– tagastab elemendid, mis jäävad kahe argumendiks antud väärtuse vahele. Kui on vajalik, et elemendid oleksid ainult suuremad või väiksemad kindlast väärtusest, kasutatakse vastavalt meetodeidheadSetjatailSet.
Lisaks on klassil TreeMap liidesest NavigableMap tulenevalt meetodid:
lowerEntry,higherEntry– tagastab võimalikult lähedase elemendi, mis on rangelt väiksem või suurem kui argument;floorEntry,ceilingEntry– tagastab argumendiga sama väärtust omava elemendi või sellele võimalikult lähedase elemendi, mis on väiksem või suurem argumendist;subMap– tagastab elemendid, mis jäävad kahe argumendiks antud väärtuse vahele. Kui on vajalik, et elemendid oleksid ainult suuremad või väiksemad kindlast väärtusest, kasutatakse vastavalt meetodeidheadMapjatailMap.
Näited mõlema kogumi tööst:
TreeSet<Integer> puuHulk = new TreeSet<>(); puuHulk.add(3); puuHulk.add(10); puuHulk.add(-4); System.out.println(puuHulk); TreeMap<Integer, String> puuKujutus = new TreeMap<>(); puuKujutus.put(70, "Hammas"); puuKujutus.put(1, "Pea"); puuKujutus.put(34, "Keel"); System.out.println(puuKujutus);Väljastab:
[-4, 3, 10]
{1=Pea, 34=Keel, 70=Hammas}
EnumSet ja EnumMap
Hulgal ja kujutusel on väärtustike kasutamiseks loodud eraldi klassid
EnumSet ja EnumMap. Nende kasutamine pole kohustuslik, aga eelisena on tavalised operatsioonid kiiremad kui klassidel HashSet ja HashMap. Mõlema elemendid (kujutusel võtmed) ei saa olla väärtusega null ja on järjestatud väärtustikuga identselt. Uute klasside kasutamiseks loome väärtustiku Olek, mille liikmed on KORRAS, KATKI ja PARANDUSES:
enum Olek {
KORRAS, KATKI, PARANDUSES
}
Klassil EnumSet on mitmeid klassimeetodeid isendite loomiseks. Meetod allOf lisab kõik väärtustiku elemendid hulka, meetod noneOf loob tühja hulga, meetod range teeb konstantide vahemikus olevatest elementidest hulga:
Set<Olek> kõikOlekud = EnumSet.allOf(Olek.class); Set<Olek> tühiOlekud = EnumSet.noneOf(Olek.class); Set<Olek> mõnedOlekud = EnumSet.range(Olek.KATKI, Olek.PARANDUSES);
Lisaks eksisteerib klassimeetod of, mille argumentidest luuakse hulk:
Set<Olek> olekuteHulk = EnumSet.of(Olek.KATKI); olekuteHulk.add(Olek.KORRAS); olekuteHulk.add(Olek.PARANDUSES); System.out.println(olekuteHulk);Väljastab:
[KORRAS, KATKI, PARANDUSES]
Klassi EnumMap isendi loomisel täpsustatakse, millist väärtustikku kasutada ning sellel ei ole EnumSet-ga sarnaseid klassimeetodeid:
Map<Olek, String> olekuteKujutus = new EnumMap<>(Olek.class); olekuteKujutus.put(Olek.KATKI, "See on halb"); olekuteKujutus.put(Olek.KORRAS, "See on hea"); olekuteKujutus.put(Olek.PARANDUSES, "See on varsti hea"); System.out.println(olekuteKujutus);Väljastab:
{KORRAS=See on hea, KATKI=See on halb, PARANDUSES=See on varsti hea}
Vector
Klassile ArrayList on väga sarnane klass
Vector, mis on vanem. See oli olemas kõige esimeses stabiilses Java väljalaskes JDK 1.0 ning hakkas realiseerima liidest List alates versioonist 1.2. Seetõttu toetab vektor võimalusi, mis on nüüdseks asendatud uute lahendustega. Näiteks meetod elements tagastab
Enumeration-tüüpi isendi. Praegu asendab seda liides Iterator, millel on sama funktsionaalsus ja elementide eemaldamise võimalus. Lisaks on vektoril mitmeid meetodeid, mida pole kirjeldatud liideses List, aga käituvad samamoodi. Näiteks addElement ja add, removeElement ja remove, removeAllElements ja clear. Tänapäeval on soovitav kasutada vektori asemel klassi ArrayList.
Vektori isendi loomine ja sellesse elementide lisamine:
Vector<Integer> vektor = new Vector<>(); vektor.add(3); vektor.add(100); vektor.add(50); System.out.println(vektor);Väljastab:
[3, 100, 50]