Kolekcie (Pokročilá JAVA epizóda 1)

180

V tomto úvodnom článku do série pokročilá java sa pozrieme na zúbok kolekciám. Kolekcie sú akoby kontajnery, ktoré v sebe držia ďalšie objekty. Inak môžeme kolekcie chápať aj ako zoznamy. Zoznam telefónnych čísiel. Zoznam osôb. Zoznam áut. Zoznam súborov. Zoznam čísiel ….

Pri kolekciách budeme hovoriť o Rozhraní, Implementácii a Algoritmoch.

Java collection framework – java sama o sebe poskytuje niekoľko kolekcií. Poskytuje nám ich implementácie a aj algoritmy na vyhľadávanie, vkladanie, triedenie a podobne.

Rozhriania kolekcií v tomto frameworku sú generické. Teda umožňujú do nich vkladať rôzne typy objektov. Pamätajte, že java je striktne typový jazyk a do premennej typu String proste int nedáš, musí tam ísť iba String. Ku generikám sa ešte dostaneme neskoršom článku.

 

Zoznam rozhraní Java collection frameworku:

Collection – top v hierarchii, používa sa na presun kolekcii, manipuláciu kde sa požaduje aby tam prišla akákoľvek kolekcia. Do Collection môžeš vložiť akýkoľvek typ kolekcie, ktorý rozširuje túto kolekciu.

Set – nemôže obsahovať duplicity

List – zoznam, môže obsahovať duplicity, poradie elementov je zachované pomocou indexov

Queue – FIFO – first in first out, čo príde prvé do tejto kolekcie tak z nej aj prvé odíde, niektoré implementácie majú výnimky

Deque – FIFO aj LIFO (last in first out) – elementy môžu byť vkladané aj vyberané z oboch koncov

Map – object ktorý mapuje objekty k ich kľúčom, nemôže obsahovať totožné kľúče

SortedSet a SortedMap – sú vlastne zoradené Map a Set

Implementácie (najpoužívanejšie sú zvýraznené boldom):

Set

EnumSet, HashSet, LinkedHashSet, TreeSet

List

ArrayList, LinkedList, Stack, Vector

Map

EnumMap, HashMap, LinkedHashMap, TreeMap

SortedSet

NavigableSet

TreeSet

SortedMap

NavigableMap

TreeMap

Queue

LinkedList, PriorityQueue

 

Set

Neobsahuje duplicitné elementy – lepšie povedané nemôže obsahovať duplicitné elementy.

HashSet – neuchováva poradie v akom boli elementy vložené ale pracuje najrýchlejšie

LinkedHashSet – uchováva poradie elementov v akom boli vložené

TreeSet – poradie elementov je zoradené podľa ich hodnôt, je pomalší

 

Majme kolekciu, ktorá obsahuje elementy, ktoré sú duplicitné. Ako z nej najrýchlejšie získame kolekciu, ktorá nemá duplicity?

Collection<Type> noDups = new HashSet<Type>(c);

Funguje to tak, že z kolekcie sa vytvorí Set. A Set už z definície nemôže obsahovať duplicity.

Pridanie elementov do Setu:

Set<String> set1 = new HashSet<>();
String s = "e";
set1.add("element1");
set1.add("element2");
set1.add("element3");
set1.add("element4");
set1.add(s);

Je element v kolekcii?

System.out.println(set1.contains("e")); //true

Odstránenie elementu z kolekcie:

set1.remove(s);

Prechádzanie cez Set:

Iterator i = set1.iterator();
while (i.hasNext()){
    System.out.println(i.next());
}

for(String s : set1) {
    System.out.println(s);
}

Spýtam sa či všetky elementy zo set1 sú aj v set2

set1.containsAll(set2)); 

Odstránim z set1 všetky zhodné elementy so set2

set1.removeAll(set2);

Všetko zo set2 pridám do set1

set1.addAll(set2);

List

Uchováva poradie elementov. Elementy sú prístupné aj pomocou indexov. Je možné do už vytvoreného Listu pridať nové elementy aj na indexy ktoré sú obsadené – elementy sa posunú. Môžeme v nich vyhľadávať indexOf a lastIndexOf. Pri Listoch si musíme dávať veľký pozor na to aby sme nezhodili program kvôli prístupu k neexistujúcim elementom – respektíve k neexistujúcim indexom v Liste. Napríklad máš List so 4 elementami a chceš pristúpiť k 6temu elementu.

 

Základné pomocné algoritmy, špecifické ku List:

  • sort — zotriedi elementy v Liste
  • shuffle — náhodne pomieša elementy v Liste.
  • reverse — otočí poradie elementov v Liste
  • rotate — otočí poradie všetkých elementov od špecifického indexu
  • swap — prehodí elementy z Listu na špecifikovaných indexoch
  • replaceAll — nahradí všetky výskyty špecifikovanej hodnoty za druhú špecifikovanú hodnotu
  • fill — prepíše všetky elementy v Liste za špecifikovanú hodnotu

 

ArrayList – prispôsobuje svoju veľkosť, základné polia museli mať špecifikovanú dĺžku pri vytvorení, nemohli rásť alebo sa zmenšovať

LinkedList – iná implementácia, rozdielu sú v časových záťažiach s rôznymi operáciami nad Listami

Pridanie elementov do Listu:

List<String> list = new ArrayList<>();
list.add("list1");
list.add("list2");
list.add("list3");
list.add("list4");
list.add("list5");

Výber elementu z listu na indexy 1:

list.get(1);

Je prázdny?

list.isEmpty();

Pridaj na pozíciu 2:

list.add(2,"list2b");

Odstráň element:

list.remove("list1");  
list.remove(4);

Rôzne manipulácie:

Collections.sort(list);
Collections.shuffle(list);
Collections.reverse(list);
Collections.rotate(list,2);
Collections.swap(list, 0, 1);
Collections.replaceAll(list, "list4", "new list4");
Collections.fill(list,"Jaro");

Map

Mapa obsahuje hodnoty viazané na kľuč. Takže to máme po anglicky key – value hodnoty. Kľúče musia byť unikátne.

HashMap – nedrží si poradie, náhodné usporiadanie

LinkedHashMap – drží poradie

Vloženie do Mapy:

Map<Integer,String> map = new HashMap<>();

map.put(10,"jaro");
map.put(1,"fero");
map.put(3,"duro");
map.put(4000,"karol");
map.put(4000,"peter"); // prepise predchádzajúci element

Získame a vypíšeme hodnotu elementu s kľúčom 1:

System.out.println(map.get(1));

Prechod cez elementy Mapy:

for(Map.Entry m : map.entrySet()){
	System.out.printf("key %d, value %s %n",m.getKey(),m.getValue());
}

for(Integer k : map.keySet()){
	map.get(k);
}

Zoradovanie

Pre zoraďovanie použijeme už existujúci algoritmus v triede Collections.sort(l). Písmeno l v tomto prípade bude List. Ak by tento List obsahoval sadu Stringov boli by zoradené abecende, ak by obsahoval Dátum tak budú zoradené chronologicky. Ako je to možné? Je to preto, lebo tieto triedy implementujú rozhranie Comparable. Ak by si sa snažil takto zoradiť také triedy, ktoré neimplementujú toto rozhranie, tak program vyhodí výnimku.

Existuje ale možnosť, že v tvojej triede implementuješ toto rozhranie. Potom toto triedenie je teraz považované za prirodzené.

Príklad: Máme Osobu, ktorá implementuje Comparable. Musíme implementovať metódu compareTo.

public class Osoba implements Comparable<Osoba>{
    private String meno;
    private String priezvisko;
    private int vek;

    public Osoba(String meno, String priezvisko, int vek) {
        this.meno = meno;
        this.priezvisko = priezvisko;
        this.vek = vek;
    }

    //get, set metódy vynechané pre čitatelnosť

    @Override
    public String toString() {
        return "Osoba{" +
                "meno='" + meno + '\'' +
                ", priezvisko='" + priezvisko + '\'' +
                ", vek=" + vek +
                '}';
    }

    @Override
    public int compareTo(Osoba o) {
        int porovnaniePriezvisk = o.getPriezvisko().compareTo(this.getPriezvisko());
        return porovnaniePriezvisk !=0 ? porovnaniePriezvisk : o.getMeno().compareTo(this.getMeno());
    }
}

Čo ak chceš použiť úplne iné ako prirodzené triedenie, chceš to triediť napríklad podľa veku. Alebo chceš triediť objekty, ktoré neimplementujú Comparable rozhranie? Tak si ho vyrobíš. Na to použiješ rozhranie Comparator a potom ho požiješ Collections.sort(e, VLASTNY_ORDER);.

public class Sort {

    private static final Comparator<Osoba> VEK_TRIEDENIE = new Comparator<Osoba>() {
        @Override
        public int compare(Osoba o1, Osoba o2) {
            return Integer.compare(o1.getVek(), o2.getVek());
        }
    };

    public static void main(String[] args) {
        Osoba[] osobyArray = {
                new Osoba("Jaro", "Beno", 20),
                new Osoba("Peter", "Beno", 25),
                new Osoba("Karol", "Slepec", 18),
                new Osoba("Tomas", "Vlak", 22)
        };

        List<Osoba> osoby = Arrays.asList(osobyArray);
        System.out.println(osoby);

        Collections.sort(osoby);
        System.out.println(osoby);

        Collections.sort(osoby, VEK_TRIEDENIE);
        System.out.println(osoby);
    }
}

Dobrý článok? Chceš dostávať ďalšie?

Už viac ako 6 200 ITečkárov dostáva správy e-mailom. Nemusíš sa báť, nie každé ráno. Len občasne.

Súhlasím so spracovaním mojich osobných údajov. ( Viac informácií. )

Tvoj email neposkytneme 3tím stranám. Posielame naňho len informácie z robime.it. Kedykoľvek sa môžeš odhlásiť.