Jelenlegi hely

21.2. Implementációk

Az implementációk az előző fejezetben leírt interfészeket valósítják meg (implementálják). Az alábbiakban az implementációk fajtáit láthatjuk.

  • Általános célú implementációk: a leggyakrabban használt implementációk, mindennapos használatra tervezték
  • Speciális célú implementációk: arra tervezték, hogy speciális helyzetekben esetében használjuk. Nem szabványos teljesítmény karakterisztikák megjelenítésére, használati és viselkedési korlátozásokra.
  • Konkurens implementációk: erős konkurencia támogatására tervezték, többnyire az egyszálú teljesítmény rovására. Ezek az implementációk a java.util.concurrent csomag részét képzik.
  • Csomagoló implementációk: a többi implementációval összekombinálva használhatók (gyakran az általános célúval), hogy extra funkcionalitást biztosítsanak, vagy bizonyos funkciókat korlátozzanak
  • Kényelmi implementációk: mini implementációk, tipikusan a gyártó metódusokon keresztül érhetők el. Kényelmes és hatékony alternatívát biztosítanak az általános célú implementációk számára speciális esetekben.
  • Absztrakt implementációk: vázlatos implementációk, amik megkönnyítik az egyéni implementációk létrehozását.

Az általános-célú implementációkat az alábbi táblázat foglalja össze:

Hash tábla Átméretezhető tömb Fa Láncolt lista Hasító tábla + Láncolt lista
Set HashSet TreeSet LinkedHashSet
List ArrayList LinkedList
Map HashMap TreeMap LinkedHashMap

A táblázatban látható hogy a Set, a List és a Map interfészek többfajta általános célú implementációja használható. A SortedSet és a SortedMap interfészeknek nincs saját sora a táblázatban, ezeknek az interfészeknek egy implementációja van (TreeSet és TreeMap).

Az általános célú implementációk mind biztosítják az összes opcionális műveletet, amit az interfészek tartalmaznak. Mindegyik megengedi a null elemet mind a kulcsok, mind az értékek esetén. Egyik sem szinkronizált. Mindegyik szerializálható (Seriaizable), és biztosít egy publikus clone metódust.

A korábbival ellentétes elképzelést jelent az a tény, hogy ezek az implementációk nem szinkronizáltak. A régebbi Vector és Hashtable gyűjtemények szinkronizáltak. A jelenlegi megközelítés azért alakult ki, mert a gyűjteményeket sűrűn használják olyan helyeken, ahol a szinkronizálhatóság nem jelent előnyt. Ilyenek például az egyszálú használat, csak olvasási használat, és ha egy olyan nagyobb adat objektum részét képzik, amely megcsinálja a saját szinkronizációját. Általános API tervezési tapasztalat az, hogy ne kötelezzük a felhasználót olyan szolgáltatás használatára, amit nem sokszor használ. Ráadásul a szükségtelen szinkronizáció adott körülmények között akár holtpontot is eredményezhet.

Általános szabály, hogy programíráskor az interfészeken, és nem az implementációkon kell gondolkodni. Ez az oka annak, hogy ebben a fejezetben nincsenek példa programok. Legtöbb esetben az implementáció megválasztása csak a teljesítményt befolyásolja. Ahogy azt a korábbiakban említettük, egy előnyben részesített programozói stílus az, ha válasszunk egy implementációt a Collection létrehozásakor, és rögtön hozzá rendeljük az új Collection-t egy olyan változóhoz, ami adott interfész típusú (vagy egy olyan eljárásnak adjuk át a Collection-t, ami egy adott interfész típusú paramétert vár). Így a program nem függ majd egy adott implementáció esetén az ahhoz hozzáadott új metódusoktól, ezáltal a programozó bármikor szabadon változtathatja az implementációt, mikor jobb teljesítményt szeretne elérni, vagy a működési részleteket módosítani.