Collections klass
Collections klass on utiilklass (utility class), mis sisaldab endas hulganisti staatilisi meetodeid, mis võimaldavad kollektsioonide peal erinevaid tegevusi läbi viia.
Näiteks see klass võimaldab kollektsioonide sorteerimist, elementide otsingut, segamist ning samuti võimaldab luua erilisi kollektsioone.
Tähtis on märkida, et see klass töötab ainult kollektsioonidega, massiividega see klass ei tegele.
Samuti ärge ajage sassi järgnevaid klasse:
Collectionon liides, mis on erinevate andmestruktuuride aluseks.Collectionson klass, millest antud artiklis räägime.
Collections klass kuulub java.util pakki ehk esmalt tuleb see nimeruumi sisse importida, näiteks:
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
// ...
List<Integer> numbers = new ArrayList<>(List.of(5, 2, 8, 1, 9));
Collections.sort(numbers); // [1, 2, 5, 8, 9]
Selle peatüki eesmärk on tutvustada erinevaid kasulike meetodeid, mida võiks vaja minna või millest võib kasu olla. Kõiki meetodeid läbima siin ei hakata.
Kollektsioonide sorteerimine ja järjestuse muutmine
Sorteerimine
Esmalt käime läbi erinevaid viise kuidas kollektsioone sorteerida.
Selle jaoks on olemas meetod Collections.sort(), kuid sellel on erinevaid nüansse.
Alustuseks kõige lihtsam viis sorteerimiseks:
List<Integer> numbers = new ArrayList<>(List.of(5, 2, 8, 1, 9));
Collections.sort(numbers);
System.out.println(numbers); // [1, 2, 5, 8, 9]
List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
Collections.sort(names);
System.out.println(names); // [Alice, Bob, Charlie]
Kui Collections.sort() meetodile sisendiks anda ainult kollektsioon, siis see eeldab, et see andmekogum koosneb elementidest, mis realiseerivad Comparable liidest.
Sõned ja arvud (Javasse sisseehitatud klassid) reeglina realiseerivad seda.
Enda poolt loodud klasside puhul peab seda ise tegema või andma sorteerimismeetodile ette Comparator ehk ise dikteerima, kuidas elemente sorteetida.
List<String> names = new ArrayList<>(List.of("Alice", "Bob", "Charlie"));
// Sort by length
Collections.sort(names, (s1, s2) ->
Integer.compare(s1.length(), s2.length()));
System.out.println(names); // [Bob, Alice, Charlie]
// Sort in reverse alphabetical order
Collections.sort(names, Collections.reverseOrder());
System.out.println(names); // [Charlie, Bob, Alice]
Järjendi ümberpööramine
Järjendi ümberpööramiseks saab kasutada Collections.reverse() meetodit:
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5));
Collections.reverse(numbers);
System.out.println(numbers); // [5, 4, 3, 2, 1]
Järjendi juhuslik segamine
Järjendi elementide juhuslikuks segamiseks saab kasutada Collections.shuffle() meetodit:
List<String> cards = new ArrayList<>(List.of("A", "2", "3", "4", "5"));
Collections.shuffle(cards);
System.out.println(cards); // Random order, e.g., [3, A, 5, 2, 4]
Järjendi elementide nihutamine
Järjendis elementide nihutamiseks saab kasutada Collections.rotate() meetodit.
Positiivne arv liigutab elemente paremale, negatiivne arv vasakule.
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5));
Collections.rotate(numbers, 2);
System.out.println(numbers); // [4, 5, 1, 2, 3]
Collections.rotate(numbers, -2);
System.out.println(numbers); // [1, 2, 3, 4, 5] (back to original)
Elementide otsing
Kahendotsing - Binary Search
Kahendotsing on otsingualgoritm, mille töö põhimõte seisneb kogumiku poolitamises. See algoritm leiab kogumikust keskmise väärtuse, võrdleb seda otsitava väärtusega ning selle põhjal otsustab millist kogumiku poolt edasi uurida. Tähtis on siin märkida, et see algoritm toimib ainult sorteeritud järjendite peal.
See algoritm töötab O(log n) kiirusel ning selleks saab kasutada Collections.binarySearch() meetodit ning tagastab otsitava elemendi indeksi:
List<Integer> numbers = new ArrayList<>(List.of(1, 3, 5, 7, 9, 11));
// List MUST be sorted first!
int index = Collections.binarySearch(numbers, 7);
System.out.println(index); // 3 (index where 7 is found)
int notFound = Collections.binarySearch(numbers, 6);
System.out.println(notFound); // Negative value
Kui sisendina antud järjend pole sorteeritud, siis tulemus võib etteaimamatu olla:
List<Integer> unsorted = new ArrayList<>(List.of(5, 2, 8, 1));
Collections.binarySearch(unsorted, 5); // Wrong - unpredictable result!
Collections.sort(unsorted);
Collections.binarySearch(unsorted, 5); // Correct
Minimaalse ja maksimaalse väärtuse leidmine
Minimaalse ja maksimaalse väärtuse leidmiseks on vastavalt Collections.min() ja Collections.max() meetodid.
List<Integer> numbers = List.of(5, 2, 8, 1, 9, 3);
int max = Collections.max(numbers);
System.out.println(max); // 9
int min = Collections.min(numbers);
System.out.println(min); // 1
// With custom comparator
List<String> words = List.of("apple", "pie", "banana");
String longest = Collections.max(words, (s1, s2) ->
Integer.compare(s1.length(), s2.length()));
System.out.println(longest); // "banana"
Kollektsioonide muundamine
Järjendi täitmine ehk kõikide elementide asendamine
Collections.fill() meetod asendab kõik järjendi elemendid ette antud väärtusega:
List<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));
Collections.fill(list, "x");
System.out.println(list); // [x, x, x, x]
Kõigi esinemiste asendamine
Collections.replaceAll() meetod asendab kõik antud elemendi esinemised järjendis:
List<String> list = new ArrayList<>(List.of("a", "b", "a", "c", "a"));
Collections.replaceAll(list, "a", "x");
System.out.println(list); // [x, b, x, c, x]
Elementide asukoha vahetamine
Collections.swap() meetod vahetab kahel indeksil asetsevad elemendid omavahel ära:
List<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));
Collections.swap(list, 0, 3);
System.out.println(list); // [d, b, c, a]
Elementide sagedus
Elemendi sageduse loendamine
Collections.frequency() abil on võimalik kokku lugeda, mitu korda üks element esineb kogumikus:
List<String> list = List.of("apple", "banana", "apple", "cherry", "apple");
int count = Collections.frequency(list, "apple");
System.out.println(count); // 3
Kattuvate elementide kontroll
Collections.disjoint() kontrollib, kas kahe kogumiku vahel esineb samu elemente:
List<Integer> list1 = List.of(1, 2, 3, 4);
List<Integer> list2 = List.of(5, 6, 7, 8);
List<Integer> list3 = List.of(3, 4, 5, 6);
boolean noCommon = Collections.disjoint(list1, list2);
System.out.println(noCommon); // true - no common elements
boolean hasCommon = Collections.disjoint(list1, list3);
System.out.println(hasCommon); // false - have common elements (3, 4)
Muutumatud kollektsionid
Collections klass võimaldab luua ka muutumatuid kollektsioone mingi kogumi põhjal.
Näiteks:
List<String> original = new ArrayList<>(List.of("a", "b", "c"));
List<String> unmodifiable =
Collections.unmodifiableList(original);
System.out.println(unmodifiable.get(0)); // "a" - reading works
unmodifiable.add("d"); // UnsupportedOperationException!
unmodifiable.remove(0); // UnsupportedOperationException!
unmodifiable.set(0, "x"); // UnsupportedOperationException!
Muutumatust kogumist on võimalik andmeid lugeda, aga neid muuta pole võimalik. See võib olla kasulik olukorras, kus mõni meetod peab tagastama kogumiku, mida meetodi väljakutsuja ei tohiks muuta. Sellisel juhul takistatakse kogumiku muutmist läbi tagastatud viite, kuid originaalkogumi muutmisel peegelduvad muudatused ka muutumatus vaates.
Muutumatud tüübid on toetatud kõikide kollektsioonide puhul:
List<String> unmodList = Collections.unmodifiableList(list);
Set<String> unmodSet = Collections.unmodifiableSet(set);
Map<String, Integer> unmodMap = Collections.unmodifiableMap(map);
Tähtis on märkida, et muutumatu kollektsioon on vaade ehk kõik muudatused, mis originaalse kogumi peal läbi viiakse tõlgenduvad ka muutumatusse kollektsiooni.
List<String> original = new ArrayList<>(List.of("a", "b"));
List<String> unmod = Collections.unmodifiableList(original);
System.out.println(unmod); // [a, b]
original.add("c");
System.out.println(unmod); // [a, b, c] - changed!
unmod.add("d"); // UnsupportedOperationException - cannot modify through view
Tühjad kollektsioonid
Samuti võimaldab Collections klass luua ka tühjasid, muutumatuid kollektsioone.
Neid kasutatakse näiteks olukorras, kus null tagastamise asemel tagastatakse tühi kogumik.
List<String> emptyList = Collections.emptyList();
Set<String> emptySet = Collections.emptySet();
Map<String, Integer> emptyMap = Collections.emptyMap();