Liigu peamise sisu juurde

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.

info

Tähtis on märkida, et see klass töötab ainult kollektsioonidega, massiividega see klass ei tegele.

Samuti ärge ajage sassi järgnevaid klasse:

  • Collection on liides, mis on erinevate andmestruktuuride aluseks.
  • Collections on 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 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();