Kihagyás

Objektumok tárolása: tömbök, kollekciók

Előadásfóliák

Tömbök Java-ban

Tömbök: objektumok; nyelvi támogatás; adott típust tárolnak (akár primitívet is), létrehozás után fix a méretük; sorrendben, indexelhető módon tárolják az elemeket.

195: A Java-ban elemek "tömeges" tárolására két lehetőség van. A nyelvi elemekkel támogatott tömbök, és a tisztán osztályokkal megvalósított kollekciók.

196: A tömbök nyelvi szinten támogatottak, gyors elérésűek, megtartják a típust (ez Java 5 előtt volt kifejezetten előny), primitív értékeket is tudnak tárolni, viszont létrehozás után fix méretűek.

197: Ahogyan a primitív típusokhoz, a tömbökhöz is léteznek általános függvények, ezek az Arrays osztályban vannak összegyűjtve (statikus metódusként), és bármilyen típusú tömbre működnek.

198: A primitív típust tároló tömbök értékeket tárolnak. Az osztály típust tároló tömbök referenciákat tárolnak. A tömbelemek megfelelő primitív vagy osztály típusú változóként viselkednek. Mivel a tömb objektum, az == művelet két tömb között referenciaegyenlőséget vizsgál. A tömb elemeinek egyenlőségét az Arrays.equals() metódussal lehet vizsgálni.

199: Tömbök elemeit az Arrays.sort() metódussal lehet sorbarendezni. Maga a rendezés algoritmusa független attól, hogy mit rendezek. Amíg két elem közül meg tudom mondani melyik kisebb, addig a rendezés szempontjából lényegtelen, hogy mi az a két elem. A rendezés maga mindössze számít arra, hogy két tömbben tárolt elem között "valaki" meg tudja adni a sorrendet. Ez a "valaki" lehet az egyik elem (Comparable), vagy egy külső, harmadik objektum (Comparator).

200: A Comparable interfész egy compareTo(Object) metódust definiál, amit a Comparable interfészt implementáló osztálynak a megfelelő módon meg kell valósítania. A rendezési algoritmus ilyen esetben két elem összehasonlításához meghívja az egyik elem compareTo metódusát a másik elemmel mint paraméterrel.

202: A Comparator interfész egy compare(Object, Object) metódust definiál. Az ezt implementáló osztály objektumai képesek lesznek a metódus implementációja alapján két másik (jellemzően adott típusú) objektumról eldönteni, melyik kisebb. Ha nem az előző "természetes" sorrendet szeretnénk használni a rendezéshez, akkor a rendező algoritmus hívásakor meg kell adni egy rendező objektumot is (egy Comparator interfészt implementáló osztály egy példányát). A rendezési algoritmus ilyen esetben ezt az objektumot fogja megkérni, hogy hasonlítsa össze a tömb két elemét.

204: A bináris keresés: veszem a rendezett tömb középső elemét, és ha nem a keresett elem az, akkor meg tudom mondani, hogy előtte vagy mögötte van-e. Ezzel a módszerrel jelentősen csökkenthető a keresési idő ahoz képest, hogy elkezdem végignézni az elemeket a tömb elejétől.

Java kollekciók

Konténerek: objektumok; nagyrészt általános objektumként kezelhetőek; Object-eket, illetve generikus kollekciók esetén adott típusú objektumokat tárolnak; változó méretűek; valamilyen egyéb logika szerint tárolnak objektumokat.

207: A konténerek - hasonlóan a tömbökhöz - több elemet képesek tárolni. Külön nyelvi támogatásuk nincs (talán csak a foreach), az elemek elérése konténerfüggő, csak objektumokat tárolhatnak, Java 5 előtt csak Object típust (azóta a generikus programozás segítségével "nem fejeltik el" az objektum típusát), és dinamikusan változhat a tárolt elemek száma.

209-210: A típusellenőrzés hiánya néha futásidőben problémát okozhat. Például egy Macska is Object, berakható a Kutyák közé. Bajt okoz, de csak futásidőben derül ki.

211: Egy tömbön, mivel soraszámozva vannak az elemei, viszonylag könnyű végigszaladni. Egy konténer elemein ez nem olyan magától értetődő, mert nem feltétlenül van az elemeknek logikai sorszáma (pl. halmaz esetén az elemek között nem feltétlenül van sorrend). A konténerek végigjárására az iterátorok használhatóak. Ha egy konténertől elkérünk egy iterátor objektumot, annak segítségével végig tudunk menni az adott konténer összes elemén (valamilyen sorrendben).

213: Az iterátorokhoz van egy java nyelvi támogatás, a foreach. Ez egy olyan for, aminek az alakja for(Típus változó : konténer), és a változó szépen felveszi a konténer összes elemének értékét, mintha egy iterátorral járnánk végig. A pontos sorrend a konténertől, annak iterátorától függ (és gyakran nem érdekes).

214: Lista: olyan konténer, amely adott sorrendben tárolja az elemeket (és az iterátorai adott sorrendben járják be azokat). Két alapvetőmegvalósítása van: ArrayList osztály (tömbös megvalósítás) és LinkedList osztály (láncolt lista).

215: Set: olyan konténer, ami nem tárol két azonos elemet. Honnan tudja, hogy két elem azonos-e? A belerakott objektumok equals() metódusait használja összehasonlításra. (Hogy ez jól működjön, az adott típusnak nem csak az equals(), de a hashCode() metódusát is felül kell definiálni. Ilyenkor figyelni kell arra, hogy ha két objektum equals() szerint egyenlő, akkor a hashCode() által visszaadott kódjuknak is egyenlőnek KELL lennie. Különböző értékű objektumok visszaadhatnak egyforma kódot.) Két alapvető megvalósítása van: a HashSet és a TreeSet osztály. Utóbbi használatához nem csak a megfelelően felüldefiniált equals() metódus, hanem a rendezhetőség is szükséges.

216: A Map-ben objektumpárokat tudunk tárolni: A kulcs-objektumok tulajdonképpen halmazként tárolódnak, és minden kulcshoz tartozik egy érték (amik már lehetnek egyformák).

Java generikus kollekciók

219: Java 5-től lehetőség van generikus programozásra, amikor "típust is megadhatunk paraméterként". A kollekvióknál ez pl. azt jelenti, hogy a kollekció nem csupán Object-eket, de bármilyen osztály típust tárolhat. Ez mondjuk eddig is így volt, hiszen minden az Object-ből származik, de ezek után a kollekció nem felejti el a típust. Vagyis nem csak annyit tudok, hogy egy Object van benne, hanem konkrétabb típust is.

220: Generikus kollekciók esetén < és > jelek között megadhatom, hogy milyen típusú objektumokat akarok tárolni (Object helyett). Innentől kezdve a fordító fordítási időben tud erre figyelni, és nem enged hülyeséget csinálni (pl. Macskát dobni a Kutyák közé). Ráadásul így a fordító azt is tudja mi van a konténerben, és olyan típussal dolgozik (nem csak Object-tel).

221-224: Nem csak a kollekciók "paraméterezhetőek" fel típusokkal, hanem sok más osztály is.


Utolsó frissítés: 2023-02-02 13:08:21