JDK 1.2 predstavuje nový rámec pre zbierky objektov, ktorý sa nazýva Java Collections Framework. „Ach nie,“ zastonáte, „ani iné API, ani iný rámec, ktorý by ste sa mali naučiť!“ Počkajte však, než sa odvrátite, vyslyšte ma: rámec Collections stojí za vaše úsilie a bude v mnohých ohľadoch prínosom pre vaše programovanie. Okamžite vám prídu na myseľ tri veľké výhody:
- Dramaticky zvyšuje čitateľnosť vašich zbierok tým, že poskytuje štandardnú sadu rozhraní, ktoré môžu používať mnohí programátori v mnohých aplikáciách.
- Zvyšuje flexibilitu vášho kódu tým, že vám umožňuje odovzdávať a vracať rozhrania namiesto konkrétnych tried, kód zovšeobecňuje a nie zamyká.
- Ponúka mnoho konkrétnych implementácií rozhraní, čo vám umožňuje vybrať si kolekciu, ktorá sa najviac hodí a ponúka najvyšší výkon pre vaše potreby.
A to len na úvod.
Naša prehliadka rámca začne prehľadom výhod, ktoré poskytuje pre ukladanie súborov objektov. Ako čoskoro zistíte, pretože vaši starí priatelia sú na koni Hashtable
a Vektor
podporujte nové API, vaše programy budú jednotné a stručné - niečo, čo vás i vývojárov pristupujúcich k vášmu kódu určite poteší.
Po našej predbežnej diskusii sa ponoríme hlbšie do podrobností.
Výhoda zbierok Java: Prehľad
Predtým, ako spoločnosť Collections urobila svoj najvítanejší debut, štandardné metódy zoskupovania objektov Java boli prostredníctvom poľa, Vektor
a Hashtable
. Všetky tieto tri kolekcie majú rôzne metódy a syntax pre prístup k členom: polia používajú symboly hranatých zátvoriek ([]), Vektor
používa elementAt
metóda a Hashtable
používa dostať
a dať
metódy. Tieto rozdiely už dávno viedli programátorov k ceste k nejednotnosti pri implementácii ich vlastných kolekcií - niektoré napodobňujú Vektor
prístupové metódy a niektoré napodobňujú Vymenovanie
rozhranie.
Aby sa veci ešte viac skomplikovali, väčšina z Vektor
metódy sú označené ako konečné; to znamená, že nemôžete rozšíriť Vektor
triedy implementovať podobný druh zberu. Mohli by sme vytvoriť triedu zbierky, ktorá by vyzerala ako Vektor
a správal sa ako Vektor
, ale nebolo možné ho preniesť na metódu, ktorá vyžaduje a Vektor
ako parameter.
Nakoniec žiadna zo zbierok (pole, Vektor
alebo Hashtable
) implementuje štandardné rozhranie pre prístup členov. Keď programátori vyvinuli algoritmy (napríklad druhy) na manipuláciu so zbierkami, spustil sa vášnivý diskurz o tom, aký objekt má byť algoritmu odovzdaný. Mali by ste zložiť pole alebo Vektor
? Mali by ste implementovať obe rozhrania? Hovorte o zdvojení a zmätku.
Našťastie rámec Java Collection Framework tieto problémy odstraňuje a ponúka množstvo výhod oproti tomu, že nepoužívate žiadny rámec alebo nepoužívate Vektor
a Hashtable
:
Použiteľná sada zberných rozhraní
Implementáciou jedného zo základných rozhraní -
Zbierka
,Nastaviť
,Zoznam
aleboMapa
- zabezpečíte, aby vaša trieda zodpovedala spoločnému API a stala sa pravidelnejšou a ľahšie pochopiteľnou. Či už implementujete databázu SQL, porovnávač vzoriek farieb alebo aplikáciu vzdialeného chatu, ak implementujeteZbierka
rozhranie, operácie s vašou zbierkou objektov sú vašim používateľom dobre známe. Štandardné rozhrania tiež zjednodušujú odovzdávanie a vracanie kolekcií do a z metód triedy a umožňujú týmto metódam pracovať na širšej palete kolekcií.Základná sada implementácií zberu
Okrem dôveryhodných
Hashtable
aVektor
, ktoré boli aktualizované s cieľom implementovaťZbierka
rozhrania, boli pridané nové implementácie kolekcií, vrátaneHashSet
aTreeSet
,ArrayList
aLinkedList
aHashMap
aMapa
. Použitím existujúcej bežnej implementácie sa váš kód stiahne kratšie a rýchlejšie. Používanie existujúceho jadra kódu Java v jadre tiež zaisťuje, že akékoľvek vylepšenia základného kódu tiež zlepšia výkonnosť vášho kódu.Ďalšie užitočné vylepšenia
Každá kolekcia teraz vracia znak
Iterátor
, vylepšený typVymenovanie
ktorý umožňuje operácie s prvkami, ako je vkladanie a mazanie. TheIterátor
je „rýchle zlyhanie“, čo znamená, že dostanete výnimku, ak zoznam, ktorý iterujete, zmení iný užívateľ. Tiež zoznamové zbierky ako naprVektor
vrátiť aListIterator
ktoré umožňujú obojsmernú iteráciu a aktualizáciu.Niekoľko zbierok (
TreeSet
aTreeMap
) implicitne podporuje objednávanie. Pomocou týchto tried môžete bez námahy udržiavať triedený zoznam. Môžete nájsť najmenšie a najväčšie prvky alebo vykonať binárne vyhľadávanie na zlepšenie výkonu veľkých zoznamov. Ďalšie zbierky môžete triediť poskytnutím metódy porovnania zbierok (aKomparátor
objekt) alebo metódu porovnania objektov (Porovnateľné
rozhranie).Na záver statická trieda
Zbierky
poskytuje neupraviteľné (iba na čítanie) a synchronizované verzie existujúcich zbierok. Nemodifikovateľné triedy pomáhajú predchádzať nežiaducim zmenám v zbierke. Synchronizovaná verzia kolekcie je nevyhnutnosťou pre programy s viacerými vláknami.
Java Collections Framework je súčasťou Core Java a je obsiahnutý v zbierky java.util.colutions
balík JDK 1.2. Rámec je k dispozícii aj ako balík pre JDK 1.1 (pozri Zdroje).
Poznámka: Je pomenovaná verzia zbierok JDK 1.1 com.sun.java.util.collections
. Majte na pamäti, že kód vyvinutý vo verzii 1.1 musí byť aktualizovaný a prekompilovaný pre 1.2 verson a všetky objekty serializované v 1.1 nemôžu byť deserializované do 1.2.
Pozrime sa teraz na tieto výhody podrobnejšie, keď použijeme rámec Java Collections Framework s vlastným kódom.
Dobré API
Prvou výhodou Java Collection Framework je konzistentné a pravidelné API. API je kodifikované v základnej sade rozhraní, Zbierka
, Nastaviť
, Zoznam
alebo Mapa
. The Zbierka
rozhranie obsahuje základné operácie zhromažďovania, ako je pridávanie, odstraňovanie a testy členstva (zadržiavanie). Akákoľvek implementácia kolekcie, či už je to poskytovaná rámcom Java Collections Framework alebo jedným z vašich vlastných výtvorov, bude podporovať jedno z týchto rozhraní. Pretože kolekčný rámec je pravidelný a konzistentný, veľkú časť rámcov sa naučíte jednoducho naučením sa týchto rozhraní.
Oboje Nastaviť
a Zoznam
implementovať Zbierka
rozhranie. The Nastaviť
rozhranie je totožné s Zbierka
rozhranie okrem dodatočnej metódy, toArray
, ktorá prevádza a Nastaviť
do Objekt
pole. The Zoznam
rozhranie tiež implementuje Zbierka
rozhranie, ale poskytuje veľa prístupových osôb, ktoré do zoznamu používajú celočíselný index. Napríklad dostať
, odstrániť
a nastaviť
všetky majú celé číslo, ktoré ovplyvňuje indexovaný prvok v zozname. The Mapa
rozhranie nie je odvodené zo zbierky, ale poskytuje rozhranie podobné metódam v java.util.Hashtable
. Klávesy sa používajú na určovanie a získavanie hodnôt. Každé z týchto rozhraní je opísané v nasledujúcich príkladoch kódu.
Nasledujúci segment kódu ukazuje, ako vykonať veľa Zbierka
operácie na HashSet
, základná zbierka, ktorá implementuje Nastaviť
rozhranie. A HashSet
je jednoducho sada, ktorá neumožňuje duplicitné prvky a neobjednáva ani neumiestňuje svoje prvky. Tento kód ukazuje, ako vytvoríte základnú kolekciu a pridáte, odstránite a otestujete prvky. Pretože Vektor
teraz podporuje Zbierka
môžete tiež tento kód spustiť na vektore, ktorý môžete otestovať zmenou HashSet
deklarácia a konštruktor na a Vektor
.
import java.util.collections. *; public class CollectionTest {// Statics public static void main (String [] args) {System.out.println ("Test zbierky"); // Vytvorenie kolekcie HashSet collection = new HashSet (); // Pridanie reťazca dog1 = "Max", dog2 = "Bailey", dog3 = "Harriet"; zbierka.pridat (pes1); zbierka.pridat (pes2); zbierka.pridat (pes3); // Dimenzovanie System.out.println ("Kolekcia bola vytvorená" + ", size =" + kolekcia.size () + ", isEmpty =" + kolekcia.isEmpty ()); // Containment System.out.println ("Zbierka obsahuje" + dog3 + ":" + zbierka.obsahuje (dog3)); // Iterácia. Iterátor podporuje hasNext, potom odstráňte System.out.println ("Kolekcia iterácie (bez triedenia):"); Iterátor iterátor = collection.iterator (); while (iterator.hasNext ()) System.out.println ("" + iterator.next ()); // Odstránenie collection.remove (dog1); collection.clear (); }}
Poďme teraz stavať na našich základných vedomostiach o zbierkach a pozrime sa na ďalšie rozhrania a implementácie v rámci Java Collections Framework.
Dobré konkrétne implementácie
Cvičili sme Zbierka
rozhranie na konkrétnej zbierke, HashSet
. Pozrime sa teraz na kompletnú sadu implementácií konkrétnych kolekcií poskytovaných v rámci zbierok Java. (Odkaz na anotovaný obrys rámca Java Collections spoločnosti Sun nájdete v časti Zdroje.)
Implementácie | ||||||
---|---|---|---|---|---|---|
Hash tabuľka | Zmena veľkosti poľa | Vyvážený strom (zoradený) | Prepojený zoznam | Dedičstvo | ||
Rozhrania | Nastaviť | HashSet | * | TreeSet | * | * |
Zoznam | * | ArrayList | * | LinkedList | Vektor | |
Mapa | HashMap | * | TreeMap | * | Hashtable |
Implementácie označené hviezdičkou (*) nedávajú zmysel alebo neposkytujú žiadny presvedčivý dôvod na implementáciu. Napríklad poskytnutie a Zoznam
rozhranie k Hash Table nemá zmysel, pretože v Hash Table nie je pojem poriadok. Podobne neexistuje č Mapa
rozhranie pre prepojený zoznam, pretože zoznam nemá pojem o vyhľadávaní tabuľky.
Poďme si teraz zacvičiť Zoznam
rozhranie tým, že pracuje na konkrétnych implementáciách, ktoré implementujú Zoznam
rozhranie, ArrayList
a LinkedList
. Kód nižšie je podobný predchádzajúcemu príkladu, ale vykonáva ho veľa Zoznam
operácie.
import java.util.collections. *; public class ListTest {// Statics public static void main (String [] args) {System.out.println ("List Test"); // Vytvorenie kolekcie ArrayList list = new ArrayList (); // Pridanie reťazca [] toys = {"Topánka", "Lopta", "Frisbee"}; list.addAll (Arrays.toList (hračky)); // Dimenzovanie System.out.println ("Zoznam vytvorený" + ", size =" + list.size () + ", isEmpty =" + list.isEmpty ()); // Iterácia pomocou indexov. System.out.println ("Zoznam iterácií (bez triedenia):"); pre (int i = 0; i <list.size (); i ++) System.out.println ("" + list.get (i)); // Reverzná iterácia pomocou ListIterator System.out.println ("List iterácia (opačne):"); ListIterator iterator = list.listIterator (list.size ()); while (iterator.hasPrevious ()) System.out.println ("" + iterator.previous ()); // Odstránenie zoznamu.remove (0); list.clear (); }}
Rovnako ako v prvom príklade je jednoduché vymeniť jednu implementáciu za druhú. Môžete použiť a LinkedList
namiesto ArrayList
jednoducho zmenou riadku s ArrayList
konštruktér. Podobne môžete použiť a Vektor
, ktorý teraz podporuje Zoznam
rozhranie.
Pri rozhodovaní medzi týmito dvoma implementáciami by ste mali zvážiť, či je zoznam nestály (často sa zväčšuje a zmenšuje) a či je prístup náhodný alebo usporiadaný. Moje vlastné testy ukázali, že ArrayList
vo všeobecnosti prekonáva LinkedList
a nový Vektor
.
Všimnite si, ako pridávame prvky do zoznamu: používame pridať všetko
statická metóda Arrays.toList
. Táto statická metóda je jednou z najužitočnejších obslužných metód v rámci kolekcií, pretože umožňuje zobrazenie ľubovoľného poľa ako Zoznam
. Teraz sa pole môže použiť kdekoľvek a Zbierka
je potrebné.
Všimnite si, že prechádzam zoznamom prostredníctvom indexovaného prístupového modulu, dostať
a ListIterator
trieda. Okrem reverznej iterácie ListIterator
trieda umožňuje pridať, odstrániť a nastaviť ľubovoľný prvok v zozname v mieste, ktoré je adresované súborom ListIterator
. Tento prístup je celkom užitočný na filtrovanie alebo aktualizáciu zoznamu po jednotlivých prvkoch.
Posledné základné rozhranie v rámci Java Collections Framework je Mapa
. Toto rozhranie je implementované s dvoma novými konkrétnymi implementáciami, TreeMap
a HashMap
. The TreeMap
je vyvážená implementácia stromu, ktorá triedi prvky podľa kľúča.
Poďme si ilustrovať použitie Mapa
rozhranie s jednoduchým príkladom, ktorý ukazuje, ako pridať, vyhľadať a vyčistiť kolekciu. Tento príklad, ktorý používa HashMap
triedy sa príliš nelíši od toho, ako sme používali Hashtable
pred debutom rámca zbierok. Teraz, s aktualizáciou Hashtable
na podporu Mapa
môžete vymeniť riadok, ktorý vytvára inštanciu HashMap
a nahradiť ho inštanciou súboru Hashtable
.