Kolekce v jazyku Java
Kolekce v programovacím jazyku Java slouží k ukládání, procházení (výběr) a mazání prvků. Java poskytuje několik typů kolekcí pro tuto funkčnost. Všechny však mají něco společného, mají společné rozhraní java.util.Collection (snad až na Map, TreeMap, SortedMap a příbuzné). Collection definuje základní metody pro práci nad kolekcemi.
Collection je základní rozhraní, od kterého dědí všechny ostatní rozhraní pro kolekce. Jaké třídy implementují rozhraní Collection můžeme nalézt v Java API (http://java.sun.com/j2se/1.5.0/docs/api/).
Když porovnáte kolekce v Java 5 s kolekcemi v Java 1.4, tak zásadní změna je v obohacení o parametrizované typy. Dále přibyly další kolekce.
Ve starších verzích Javy (verze 1.1) byla dostupná pouze kolekce Vector. Vector se dal procházet buď indexově (jako pole) nebo pomocí Enumeration. V několika knihách jsem se dočetl, že Vector je zastaralý a neměl by se používat. Měl by se, podle nich, na místo Vector použít ArrayList. Abych Vector neoprávněně neodsuzoval, udělal jsem si malý výkonnostní test a vyšlo mi, že Vector je pomalejší od ArrayList o nějakých cca 10%. Není to ovšem vina špatných algoritmů, nebo špatné implementace. Je to proto, že Vector je serializovaný a ArrayList nikoli. Proto Vector není nijak zastaralý a odsouzený k zániku. Je nevýkonný tehdy, když ho použijete na špatném místě. Jak to bývá ostatně kdykoli, když se používají nesprávné postupy, když člověk neví co přesně a proč dělá. Kdyby ho autoři jazyka nechtěli, tak by ho snad daly alespoň deprecated.
Proto řeči "Já mám raději ArrayList, protože je novější, Vector je zastaralý a pomalý!" jsou neopodstatněné.
Od verze 1.2 byly do Javy přidány další kolekce a byla rozšířena jejich funkčnost.
Základní rozdělení v rozhraní (s příslušnými podtřídami):
1. Collection
1.1 List (ArrayList, Vector, Stack)
1.2 Set (HashSet, LinkedHashSet)
1.2.1 SortedMap (TreeSet)
1.3 Queue (LinkedList)
2 Map (SortedMap, HashMap, LinkedHashMap, Hashtable, WeakHashMap)
2.1 SortedMap (TreeMap)
Seznam není úlpný a ani není třeba ho ani doplňovat. Například v seznamu chybí kolekce pro Enum, ale o těch bych se chtěl rozepsat někdy jindy a podrobněji. Pro to, jaké kolekce nám Java poskytuje se stačí podívat do API.
Nyní si popíšeme a ukážeme vhodné použití kolekcí. Při popisu nebudu vypisovat všechny metody, které kolekce poskytují. Budu se více zaměřovat na funkcionalitu, vhodné použití a optimalizaci.
1. ArrayList
ArrayList je jedna ze základních kolekcí. Je to třída, která implementuje rozhraní List. Jednoduše se dá říct, že je to dynamické (nafukovací) pole. O bufferování ArrayListu se můžeme prosadit sami, nebo to nechat na automatické správě bufferu ArrayListu.
Pokud chceme a víme, že budeme potřebovat vložit do ArrayList 10 000 prvků hned při vložení, ArrayList patřičně inicializujeme: new ArrayList(10000). Pokud nevíme kolik prvků bude vloženo do kolekce (a víme, že jich moc nebude) inicializujeme třídu ArrayList výchozím postupem: new ArrayList().
Příklad: Při vytvoření ArrayList se inicializuje pole o velikosti například 1 000. Až vyplníme kolekci (pole), vytvoří se jiné větší pole, do kterého se překopíruje obsah předchozího pole. A můžeme pokračovat v plnění. Jde vidět, že se ArrayList chová jako StringBuffer.
Pokud bychom chtěli aplikaci optimalizovat a vyladit práci s kolekcemi, můžeme si napsat malý statistický program. Ten by nám zjišťoval jaká je počáteční velikost, velikost po naplnění a velikost po některém dalším přidání prvků. Z toho bychom viděli a měli přesný přehled s jakou hodnotou inicializovat ArrayList.
Další věc, kterou bychom měli dodržovat a každé rozumné IDE to vyžaduje, je vytvářet typově bezpečné kolekce. Když nebyly generické typy (parametrizované typy, šablony, ...) vytvářely se třídy, které zaobalily kolekcí a nedovolily nikomu vložit do kolekce dva nebo více různých typů.
Zjednodušeně něco jako toto:
S použitím generických typů se všechno zjednodušuje a odpadá nutnost implementovat tuto třídu. Typově bezpečnou kolekci vytvoříme takto:
O tom co to znamená jsem už něco napsal, tak se na to teď odkazuji.
2. Vector
Vector má stejně jako ArrayList stejné předky. Liší se od ArrayListu tím, že je synchronizovaný.
3. Stack
4. HashSet
5. LinkedHashSet
6. TreeSet
7. LinkedList
8. SortedMap
9. HashMap
10. LinkedHashMap
11. Hashtable
12. WeakHashMap
13. TreeMap
Collection je základní rozhraní, od kterého dědí všechny ostatní rozhraní pro kolekce. Jaké třídy implementují rozhraní Collection můžeme nalézt v Java API (http://java.sun.com/j2se/1.5.0/docs/api/).
Když porovnáte kolekce v Java 5 s kolekcemi v Java 1.4, tak zásadní změna je v obohacení o parametrizované typy. Dále přibyly další kolekce.
Ve starších verzích Javy (verze 1.1) byla dostupná pouze kolekce Vector. Vector se dal procházet buď indexově (jako pole) nebo pomocí Enumeration. V několika knihách jsem se dočetl, že Vector je zastaralý a neměl by se používat. Měl by se, podle nich, na místo Vector použít ArrayList. Abych Vector neoprávněně neodsuzoval, udělal jsem si malý výkonnostní test a vyšlo mi, že Vector je pomalejší od ArrayList o nějakých cca 10%. Není to ovšem vina špatných algoritmů, nebo špatné implementace. Je to proto, že Vector je serializovaný a ArrayList nikoli. Proto Vector není nijak zastaralý a odsouzený k zániku. Je nevýkonný tehdy, když ho použijete na špatném místě. Jak to bývá ostatně kdykoli, když se používají nesprávné postupy, když člověk neví co přesně a proč dělá. Kdyby ho autoři jazyka nechtěli, tak by ho snad daly alespoň deprecated.
Proto řeči "Já mám raději ArrayList, protože je novější, Vector je zastaralý a pomalý!" jsou neopodstatněné.
Od verze 1.2 byly do Javy přidány další kolekce a byla rozšířena jejich funkčnost.
Základní rozdělení v rozhraní (s příslušnými podtřídami):
1. Collection
1.1 List (ArrayList, Vector, Stack)
1.2 Set (HashSet, LinkedHashSet)
1.2.1 SortedMap (TreeSet)
1.3 Queue (LinkedList)
2 Map (SortedMap, HashMap, LinkedHashMap, Hashtable, WeakHashMap)
2.1 SortedMap (TreeMap)
Seznam není úlpný a ani není třeba ho ani doplňovat. Například v seznamu chybí kolekce pro Enum, ale o těch bych se chtěl rozepsat někdy jindy a podrobněji. Pro to, jaké kolekce nám Java poskytuje se stačí podívat do API.
Nyní si popíšeme a ukážeme vhodné použití kolekcí. Při popisu nebudu vypisovat všechny metody, které kolekce poskytují. Budu se více zaměřovat na funkcionalitu, vhodné použití a optimalizaci.
1. ArrayList
ArrayList je jedna ze základních kolekcí. Je to třída, která implementuje rozhraní List. Jednoduše se dá říct, že je to dynamické (nafukovací) pole. O bufferování ArrayListu se můžeme prosadit sami, nebo to nechat na automatické správě bufferu ArrayListu.
Pokud chceme a víme, že budeme potřebovat vložit do ArrayList 10 000 prvků hned při vložení, ArrayList patřičně inicializujeme: new ArrayList(10000). Pokud nevíme kolik prvků bude vloženo do kolekce (a víme, že jich moc nebude) inicializujeme třídu ArrayList výchozím postupem: new ArrayList().
Příklad: Při vytvoření ArrayList se inicializuje pole o velikosti například 1 000. Až vyplníme kolekci (pole), vytvoří se jiné větší pole, do kterého se překopíruje obsah předchozího pole. A můžeme pokračovat v plnění. Jde vidět, že se ArrayList chová jako StringBuffer.
Pokud bychom chtěli aplikaci optimalizovat a vyladit práci s kolekcemi, můžeme si napsat malý statistický program. Ten by nám zjišťoval jaká je počáteční velikost, velikost po naplnění a velikost po některém dalším přidání prvků. Z toho bychom viděli a měli přesný přehled s jakou hodnotou inicializovat ArrayList.
Další věc, kterou bychom měli dodržovat a každé rozumné IDE to vyžaduje, je vytvářet typově bezpečné kolekce. Když nebyly generické typy (parametrizované typy, šablony, ...) vytvářely se třídy, které zaobalily kolekcí a nedovolily nikomu vložit do kolekce dva nebo více různých typů.
Zjednodušeně něco jako toto:
class StringArrayList {
private List list = new ArrayList();
public void add(String s) {
list.add(s);
}
public String get(int i) {
return (String) list.get(i);
}
}
S použitím generických typů se všechno zjednodušuje a odpadá nutnost implementovat tuto třídu. Typově bezpečnou kolekci vytvoříme takto:
List <String> list = new ArrayList <String>().O tom co to znamená jsem už něco napsal, tak se na to teď odkazuji.
2. Vector
Vector má stejně jako ArrayList stejné předky. Liší se od ArrayListu tím, že je synchronizovaný.
3. Stack
4. HashSet
5. LinkedHashSet
6. TreeSet
7. LinkedList
8. SortedMap
9. HashMap
10. LinkedHashMap
11. Hashtable
12. WeakHashMap
13. TreeMap

