IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 11 - ArrayList v Javě

Dnes si v tutoriálu ukážeme jednu kolekci, která je chytřejší, než pole. Umožňuje totiž prvky libovolně přidávat a mazat.

Pojem kolekce jsme tu již zmínili. Je to struktura, do které můžeme ukládat více objektů. Kolekcí je v Javě velké množství, jsou uzpůsobeny na různé účely a můžeme s nimi zacházet různými způsoby. Proto jim je věnována celá sekce. Dosud známe pouze kolekci pole. V průběhu seriálu však budeme potřebovat něco chytřejšího, kam budeme moci jednoduše za běhu programu přidávat a mazat záznamy. Jistě by se nám hodilo si v paměti spravovat databázi nějakých objektů. Víme, že pole má konstantní velikost, což je daň za jeho vysokou rychlost. Nyní si představíme třídu ArrayList, kterou můžeme již podle názvu chápat jako nadstavbu pole.

ArrayList

ArrayList je tzv. generická kolekce. Pojem genericita si plně vysvětlíme až u kolekcí, nyní nám bude stačit vědět, že při deklaraci kolekce ArrayList specifikujeme datový typ objektů, které v něm budou uloženy. Začněme jednoduše a udělejme si ArrayList čísel, která budeme náhodně losovat.

Losování

Program se nás vždy zeptá, zda chceme losovat další číslo a to se přidá do kolekce ArrayList. Pokud již nebudeme chtít losovat, program vypíše losovaná čísla, seřazená od nejmenšího po největší. Založme si nový projekt Losovani a vytvořme si třídu Losovac. Třída bude obsahovat kolekci ArrayList typu Integer, kde budou čísla uložena.

Narážíme na třídu Integer, která slouží k uložení celých čísel a v podstatě obaluje datový typ int. Do ArrayListu se totiž dají vkládat pouze objekty, tedy proměnné referenčního typu. Pro tyto účely existuje typ Integer. Ke každému primitivnímu typu v Javě existuje jeho referenční "obal", brzy si je uvedeme. Kolekce ArrayList bude privátní a bude sloužit pouze jako interní úložiště dané třídy, aby se na něj zvenku nedalo přistupovat.

Kolekci ArrayList deklarujeme takto:

ArrayList<Integer> cisla;

Datový typ píšeme u generických kolekcí do špičatých závorek. Kolekce ArrayList je samozřejmě objekt, jako každý jiný. Stejně jako u pole a jiných objektů, i zde proměnnou před použitím inicializujeme:

ArrayList<Integer> cisla = new ArrayList<Integer>();

Všimněte si závorek, které značí konstruktor. Takovýto list tedy umístíme do naší třídy, spolu s náhodným generátorem Random. Pro práci s třídou ArrayList je třeba přidat import java.util.ArrayList. V konstruktoru atributy inicializujeme:

import java.util.ArrayList;
import java.util.Random;

public class Losovac {
    private ArrayList<Integer> cisla;
    private Random random;

    public Losovac() {
        random = new Random();
        cisla = new ArrayList<Integer>();
    }
}

Dále přidáme metody losuj() a vypis(), kde losuj() přidá do ArrayListu nové náhodné číslo a také ho vrátí jako návratovou hodnotu. Metoda vypis() vrátí textový řetězec pro vypsání. Ten bude obsahovat čísla z kolekce cisla, seřazená a oddělená mezerou.

Losování náhodného čísla již známe z dílu o hrací kostce, zde budeme vyhazovat čísla od 1 do 100. Číslo do ArrayListu přidáme pomocí metody add():

public int losuj() {
    Integer cislo = random.nextInt(100) + 1;
    cisla.add(cislo);
    return cislo;
}

Velmi jednoduché, že? Kolekce ArrayList je interně poměrně složitá a zatím se nebudeme zabývat tím, co se uvnitř děje. To je ostatně účel Javy, nabízet kvalitní a sofistikované komponenty, které se jednoduše používají.

Výpis čísel bude ještě snazší. K setřídění kolekce ArrayList použijeme metodu sort() ze třídy Collections, která list setřídí. Bude tedy potřeba importovat java.util.Collections. Metoda nic nevrací, pouze ArrayList setřídí uvnitř:

public String vypis() {
    String vypis = "";
    Collections.sort(cisla);
    for (int cislo : cisla) {
        vypis += cislo + " ";
    }
    return vypis;
}

Hotovo.

Přesuňme se do metody main() a pomocí cyklu while umožněme uživateli ovládat objekt. Podobný program byla kalkulačka z prvních lekcích, kde jsme se v cyklu ptali, zda si uživatel přeje opakovat výpočet. Zde budeme postupovat totožně.

Ovládání bude pomocí možností 1, 2, 3 (losuj, vypiš, konec). Budeme je načítat pomocí metody scanner.nextLine() jako String:

Scanner scanner = new Scanner(System.in);
Losovac losovac = new Losovac();
System.out.println("Vítejte v programu losování.");
String volba = "0";
// hlavní cyklus
while (!volba.equals("3")) {
    // výpis možností
    System.out.println("1 - Losovat další číslo");
    System.out.println("2 - Vypsat čísla");
    System.out.println("3 - Konec");
    volba = scanner.nextLine();
    System.out.println();
    // reakce na volbu
    switch (volba) {
        case "1":
            System.out.printf("Padlo číslo: %s%n", losovac.losuj());
            break;
        case "2":
            System.out.printf("Padla čísla: %s%n", losovac.vypis());
            break;
        case "3":
            System.out.println("Děkuji za použití programu");
            break;
        default:
            System.out.println("Neplatná volba, zadejte prosím znovu.");
            break;
    }
}

Nezapomeneme na import třídy Scanner. IDE většinou toto zvládne dělat za nás :)

  • V IntelliJ stačí například stisknutí klávesy Tab při psaní třídy Scanner:
    Objektově orientované programování v Javě
  • V NetBeans stačí kliknout pravým tlačítkem na třídu Scanner a zvolit z nabídky Fix imports, případně použít klávesovou zkratku Ctrl + Shift + I.

Průběh programu je z kódu dobře viditelný, nejprve nastavíme volbu na nějakou výchozí hodnotu, aby cyklus poprvé proběhl. Poté volbu načteme z klávesnice. String zpracujeme pomocí konstrukce switch a provedeme příslušné akce. Pokud bylo zadáno něco jiného, pokryje to možnost default:

Konzolová aplikace
3 - Konec
1
Padlo číslo: 52
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec
1
Padlo číslo: 40
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec
1
Padlo číslo: 62
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec
2
Padla čísla: 2 6 7 7 8 8 9 9 10 10 12 14 17 19 19 21 23 25 25 27 27 27 28 28 28 30 30 31 32 33 33 35 35 36 36 36 37 38 38 40 41 42 42 42 44 45 45 45 45 45 48 51 52 52 53 55 56 56 56 57 58 58 59 61 62 66 68 68 71 72 73 73 74 76 82 83 84 84 85 87 88 88 89 90 90 91 93 94 98 98 98 99 100
1 - Losovat další číslo
2 - Vypsat čísla
3 - Konec

Vidíme, že můžeme stále přidávat nová a nová čísla. Máme mnohem větší možnosti než s polem. Zároveň však můžeme s ArrayListem pracovat podobně, jako jsme pracovali s polem.

K přístupu můžeme využít metody get() a set(), ale pozor, prvek musí existovat. Zkusme si napsat následující kód:

ArrayList<String> polozky = new ArrayList<String>();
polozky.add("První");
System.out.println(polozky.get(0));
polozky.set(0, "První položka");
System.out.println(polozky.get(0));
polozky.set(1, "Druhá položka");  // vyhodí chybu

Vytvoříme si list textových řetězců. Přidáme položku První a poté vypíšeme položku na indexu 0. Vypíše se nám První. Můžeme na ni samozřejmě i takto zapisovat. S druhou položkou na pozici 1 však již nemůžeme pracovat, protože jsme ji do listu nepřidali. U pole jsme zadali velikost a on všechny "přihrádky" (proměnné pod indexy) založil. Nyní velikost nezadáváme a "přihrádky" si přidáváme sami.

Podívejme se na ArrayList podrobněji a vypišme si metody, které jsou pro nás nyní zajímavé.

Konstruktory

Kromě prázdného ArrayListu můžeme List vytvořit i jako kopii z jiného listu, pole nebo jiné kolekce. Stačí kolekci předat do konstruktoru:

        String[] retezce = {"První", "Druhá", "Třetí"};
        ArrayList<String> polozky = new ArrayList<String>(Arrays.asList(retezce));
        System.out.println(polozky.get(2));

Kód výše vypíše Třetí:

Konzolová aplikace
Třetí

Prvky pole se do nového listu zkopírují. Stejně můžeme předat i jiný ArrayList.

Metody na třídě ArrayList

Ukážeme si pár důležitých metod, které můžeme volat na třídě ArrayList:

  • size() - Funguje jako metoda length() na poli, vrací počet prvků v kolekci.
  • add(položka) - Metodu add() jsme si již vyzkoušeli, jako parametr bere položku, kterou vloží do listu.
  • addAll(kolekce) - Přidá do listu více položek, např. z pole.
  • clear() - Odstraní všechny položky v listu.
  • contains(položka) - Vrací hodnoty true nebo false podle toho, zda ArrayList obsahuje předanou položku.
  • indexOf(položka) - Vrátí index prvního výskytu položky (jako u pole). Vrací hodnotu -1 při neúspěchu.
  • lastIndexOf(položka) - Vrací index posledního výskytu položky v listu. Vrací hodnotu -1 při neúspěchu.
  • remove(index) - Odstraní položku na daném indexu.
  • removeAll(kolekce) - Odstraní všechny položky v listu (podobná jako metoda clear(), ale pomalejší - dělá další kroky navíc)
  • toArray() - Zkopíruje položky z ArrayListu do pole a to vrátí.

Další metody

Další metody a pro práci s listem najdeme ve třídě Collections. Jako parametr berou danou kolekci:

  • min() - Vrátí nejmenší prvek z kolekce.
  • max() - Vrátí největší prvek z kolekce.
  • reverse() - Obrátí list tak, že je první položka poslední a naopak. Metoda nic nevrací, změny se provedou v zadaném listu.
  • sort() - Metodu sort() již také známe, setřídí položky v listu. Metoda opět nic nevrací.

Vidíme, že kolekce ArrayList toho umí mnohem více, než pole. Největší výhodou je přidávání a mazání prvků. Daň ve výkonu je zanedbatelná. V sekci s kolekcemi zjistíme, že kolekce ArrayList má ještě další metody, ale zatím na to nemáme zkušenosti.

Program pro ukládání losovaných čísel byl zajímavý, ale jistě se nám bude v budoucnu hodit ukládat spíše plnohodnotné objekty, než čísla.

V následujícím cvičení, Řešené úlohy k 11. lekci OOP v Javě, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 971x (23.1 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Kvíz - Dědičnost, statika, gettery a settery v Javě OOP
Všechny články v sekci
Objektově orientované programování v Javě
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 11. lekci OOP v Javě
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
441 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity