LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Java (10) - Kontejnery I.

Kontejnery (v Javě obvykle nazývané "kolekce") jsou objekty, které nám umožňují snadno a efektivně spravovat variabilní hromadná data. Dají se s nimi dělat úžasné věci.

23.3.2005 15:00 | Lukáš Jelínek | Články autora | přečteno 72646×

Úvod do problematiky

Proč kontejnery

Pole, s nimiž jsme se seznámili v předchozích kapitolách, mají několik zásadních nevýhod. Nemohou měnit svoji velikost (mají předem daný počet prvků), lze k nim přistupovat jen podle číselného indexu, řazení prvků se musí provádět externě a explicitně, k manipulacím s poli nelze přidávat vedlejší efekty (které se někdy hodí). Proto už hodně dávno vzniklo něco, čemu se obecně říká kontejnery.

Kontejner je datový objekt, obsahující "v sobě" nějaké další objekty, ke kterým lze různým způsobem přistupovat a pracovat s nimi. Podle způsobů uložení dat a práce s nimi rozlišujeme různé druhy kontejnerů a při jejich použití si vždy vybereme ten, který se pro daný případ nejlépe hodí.

V Javě se kontejnerům většinou říká kolekce (proto budu v dalším textu používat i tento termín), jejich chování se částečně podobá kontejnerům, které programátoři v C++ znají z knihovny STL. S javovskými kolekcemi se však pracuje trochu odlišně - dá se říci názorněji, avšak za cenu většího množství napsaného kódu.

The Collections Framework

Pod tímto názvem (dále budu používat "CF") se skrývá celý systém rozhraní a tříd, které bezprostředně souvisí s kolekcemi. Naprostou většinu z nich najdeme v balíku java.util (na jiné umístění včas upozorním). Důležitým faktem je, že v Javě 5.0 (tj. od JDK 1.5.0) došlo v CF k významným změnám (které CF částečně posunuly směrem k STL). Všechna další vysvětlení a příklady se budou týkat JDK verze 1.4.2, změny provedené ve verzi 1.5.0 uvedu na závěr.

Práce s kolekcemi se rozhodně neomezuje jen na knihovnu CF, právě naopak. S výhodou si můžeme vytvářet vlastní kontejnery a implementovat např. různé vedlejší efekty operací, vlastní způsob uložení dat (když to hodně přeženu, kontejner lze třeba i přímo napojit na databázi), přidávat své vlastní operace atd. Kdo si dobře zažije práci s hotovými objekty, sám přijde na to, co mu případně chybí.

Důležité pojmy

I když není dobré přehánět to se suchou teorií, zde se jí (v zájmu dobrého pochopení funkce jednotlivých kontejnerů) težko vyhneme. Ale nebude jí mnoho...

Iterátor je prostředek zajišťující sekvenční přístup k datům. Pracuje krokově, v každém dalším poskytne přístup k dalšímu prvku. Používá se tehdy, když potřebujeme postupně pracovat s jednotlivými prvky a buď nezáleží na pořadí, nebo pořadí vyplývá z vlastností kolekce, nad níž iterátor pracuje. Potřebujeme-li pracovat s prvky právě tímto způsobem (např. z každého něco přečíst), měli bychom vždy používat iterátory, protože bývají implementovány tak, aby to pro uvedené použití bylo nejrychlejší.

Porovnatelnost objektů je důležitá vlastnost, kterou potřebujeme pro uložení do některých kontejnerů. Je to tehdy, když se objekty uspořádávají v přirozeném pořadí (v základním způsobu uspořádání). Zjišťuje se, zda jsou objekty sobě rovny, nebo je jeden z nich "větší" či "menší" než druhý (u číselných hodnot je význam jasný; ostatní datové objekty mohou mít porovnatelnost implementovánu prakticky libovolným způsobem). V Javě je porovnatelnost zaručena tím, že třída implementuje rozhraní Comparable (obsahuje jedinou metodu compareTo()).

Většina standardních tříd rozhraní Comparable neimplementuje - ani tam není vše ztraceno. Můžeme totiž vytvořit tzv. komparátor (rozhraní Comparator), který lze použít neomezeně, s libovolnými objekty (záleží pouze na jeho implementaci). Komparátor zajišťuje úplné uspořádání objektů (pomocí operací porovnání a testu rovnosti), můžeme ho použít jak při explicitním řazení prvků, tak ho předat některým kolekcím pro použití k vnitřnímu uspořádání.

Volba vhodného kontejneru

I když u každého typu kontejneru vždy vysvětlím, k čemu se daný typ hodí, obecný úvod udělám ihned. Máme totiž k dispozici širokou škálu kolekcí v různých kategoriích a správná volba je důležitá z hlediska dobré funkce programu a jeho rychlosti. Obvykle posuzujeme tato hlediska:

  • Způsob práce (sekvenční nebo náhodný přístup) - různé typy kontejnerů se hodí pro určité způsoby přístupu, je nutné s tím předem počítat. Lze říci, že kolekce vhodné pro náhodný přístup se dají docela dobře použít i pro přístup sekvenční, ale spotřebuje se vždy více paměti, než by bylo nutné při volbě kolekce přímo pro sekvenční přístup.
  • Četnost čtení, přidávání, odebírání, přesunů - platí totéž co pro náhodný a sekveční přístup. Je dobré si toto předem ujasnit, při nejasnosti provést během ladění testy s různými typy kolekcí a měřit rychlost a spotřebu paměti (i když se to někdy dělá dost špatně). Je třeba si rovněž uvědomit, že ne všechny kontejnery musí nutně implementovat všechny manipulační operace.
  • Vláknová bezpečnost - k vláknům se dostaneme sice až někdy později, ale už teď je důležité, že by během manipulačních operací kontejneru (kdy je kontejner v nekonzistentním stavu) k němu nemělo přistupovat více vláken. Musí se "nějak" zajistit synchronizace přístupu - některé kolekce synchronizaci obsahují (spíše ty starší), jiné nikoliv (je to rychlejší). Pokud použijeme kontejner bez synchronizace a mohlo by dojít k současnému přístupu více vláken, je třeba synchronizovat přístup přímo v programu.
  • Volba vhodného rozhraní - při vlastní práci s kolekcemi (kromě jejich vytváření) je vhodné používat rozhraní, která jsou společná většímu počtu kolekcí. Kód je pak obecnější a usnadní se tím případná změna implementační třídy kolekce.

Poznámky pro programátory v C++

Tvůrci Javy říkají, že zatímco v STL jsou středobodem iterátory, v javovských kolekcích jsou podružnou záležitostí - v řadě případů se obejdeme bez nich. Skutečně, u spousty použití kontejnerů v Javě o iterátory ani nezavadíme. Dostaneme se k tomu později v příkladech.

Příjemnou věcí je naopak fakt, že narozdíl od STL se javovské kolekce chovají na všech platformách stejně (jako většina věcí v Javě). Další podstatný rozdíl je ten, že v Javě se obecně nevyskytují (až na malé výjimky), narozdíl od C++, přetížené operátory - to platí i pro kontejnery a s nimi spojené iterátory. Pracujeme s nimi prostřednictvím volání různých metod.

Základy práce s kolekcemi

Jednoduchý příklad

Než se pustíme do postupného poznávání světa The Collections Framework, bude dobré si nejprve ukázat, co to vlastně umí. Jako příklad jsem zvolil práci se třídou Vector, která byla jednou z prvních implementací kontejnerů (ještě před vznikem CF) a představuje vlastně pole s proměnnou velikostí:

Vector v = new Vector();  // vytvoří instanci s výchozími parametry

v.add("abcd");            // vloží textový řetězec
v.add(new Integer(6));    // vloží celé číslo
v.add(1, "efgh");         // vloží textový řetězec na pozici 1

System.out.println("Na pozici 1 je: " + v.elementAt(1));

System.out.println("Obsah vektoru:");
Iterator it = v.iterator();
while (it.hasNext()) {            // opakuj, dokud jsou položky
  System.out.println(it.next());  // tisk další položky
}

v.clear();      // smazání obsahu

V uvedeném příkladě se vytvoří instance třídy Vector s výchozími parametry. Pak do něj přidáme tři objekty: řetězec (přidá se na konec), celé číslo (opět na konec) a znovu řetězec (vloží se na pozici 1, data od této pozice se tím posunou). Indexy se (stejně jako u polí) číslují od nuly. Pokud chceme vložit primitivní datový objekt, musíme použít "zapouzdřující" referenční typ - v tomto případě pro int použijeme typ Integer.

Na dalším řádku je vidět přímý přístup k prvku přes jeho index. Metoda elementAt pracuje obdobně jako operátor hranatých závorek u polí - a to včetně toho, že se při přístupu mimo platný rozsah vyvolá výjimka ArrayIndexOutOfBoundsException. Co se naopak liší, je vrácený typ. U polí jsme zvyklí na to, že máme vždy hodnotu toho typu, jakého je pole. U kolekcí tomu tak není, prvky se vrací jako typ Object a o správné přetypování se musíme postarat sami. Ve výše uvedeném případě na tom nezáleží, neboť se stejně vše převede na řetězec.

Pak tu máme ukázku práce s iterátorem. Ten získáme obecně metodou iterator() a pracujeme s ním pomocí dvojice metod hasNext() (zjistí, zda jsou k dispozici další položky) a next() (vrátí následující položku). Prvky jsou opět v podobě referencí na Object. Závěrečné volání vymaže obsah celého vektoru (odstraní všechny položky).

Výše uvedený příklad a další podobný (složitější) najdete i s komentáři v ukázkovém zdrojovém souboru ContainerExample.java, který si můžete stáhnout a zkompilovat. Pozn.: Pokud budete zkoušet kompilovat na Javě 5.0 (JDK 1.5.x), kompilátor vypíše varování. Nedělejte si s ním starosti, brzy si řekneme, proč to dělá.

Podrobnější seznámení s kolekcemi

Doufám, že jsem vás tímto nezáživným, obecným a téměř ryze teoretickým úvodem do světa javovských kontejnerů neznechutil natolik, že byste o ně ztratili zájem. Byla by to škoda, příště totiž přijde řada na jednotlivé kategorie a konkrétní implementace kolekcí - jak pracují, co umí a neumí, k čemu se hodí a jak je správně použít.

Verze pro tisk

pridej.cz

 

DISKUZE

Pěkné... 25.3.2005 12:51 Lukáš Zapletal
L Re: Pěkné... 25.3.2005 13:43 Lukáš Jelínek
Vector 29.1.2008 09:54 Jan Kurš




Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

18.6.2018 0:43 /František Kučera

Červnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 21. 6. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: F-Droid, aneb svobodný software do vašeho mobilu. Kromě toho budou k vidění i vývojové desky HiFive1 se svobodným/otevřeným čipem RISC-V.


Přidat komentář

23.5.2018 20:55 /Ondřej Čečák
Od pátku 25.5. proběhne na Fakultě informačních technologií ČVUT v Praze openSUSE Conference. Můžete se těšit na spostu zajímavých přednášek, workshopů a také na Release Party nového openSUSE leap 15.0. V na stejném místě proběhne v sobotu 26.5. i seminář o bezpečnosti CryptoFest.
Přidat komentář

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

14.5.2018 7:28 /František Kučera
Květnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 17. 5. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: Audio – zvuk v GNU/Linuxu.
Přidat komentář

7.5.2018 16:20 /František Kučera
Na stránkách spolku OpenAlt vyšla fotoreportáž Pražské srazy 2017 dokumentující srazy za uplynulý rok. Květnový pražský sraz na téma audio se bude konat 17. 5. 2018 (místo a čas ještě upřesníme).
Přidat komentář

17.4.2018 0:46 /František Kučera
Dubnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 4. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tématem tohoto srazu bude OpenStreetMap (OSM) aneb svobodné mapy.
Přidat komentář

16.3.2018 22:01 /František Kučera
Kulatý OpenAlt sraz v Praze oslavíme klasicky: u limonády a piva! Přijďte si posedět, dát si dobré jídlo a vybrat z mnoha piv do restaurace Kulový blesk, který najdete v centru Prahy nedaleko metra I. P. Pavlova na adrese Sokolská 13, Praha 2. Sraz se koná ve čtvrtek 22. března a začínáme v 18:00. Heslo: OpenAlt. Vezměte s sebou svoje hračky! Uvítáme, když si s sebou na sraz vezmete svoje oblíbené hračky. Jestli máte nějaký drobný projekt postavený na Arduinu, nějakou zajímavou elektronickou součástku, či třeba i pěkný úlovek z crowdfundingové akce, neváhejte. Oslníte ostatní a o zábavu bude postaráno.
Přidat komentář

13.2.2018 0:41 /František Kučera
Únorový pražský sraz OpenAltu se koná 15. 2. 2018 a tentokrát se vydáme na návštěvu do jednoho pražského datacentra. Sejdeme se v 17:50 v severovýchodní části nástupiště tramvajové zastávky Koh-I-Noor. Po exkurzi se přesuneme do restaurace U Pštrosa (Moskevská 49), kde probereme tradiční témata (svobodný software a hardware, DIY, CNC, SDR, 3D tisk…) a tentokrát bude k vidění i IoT brána od The Things Network.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

16.1.2018 1:08 / Ivan Pittner
verejna ip od o2 ubuntu

15.1.2018 17:26 / Mira Harvalik
Re: Jak udělat HTML/Javascript swiping gallery do mobilu?

30.12.2017 20:16 / Michal Knoll
odmocnina

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze