Általános tömb létrehozása Java-ban

1. Bemutatkozás

A tömböket olyan osztályok vagy funkciók részeként használhatjuk, amelyek támogatják a generikákat. A Java kezelésének módja miatt ez nehéz lehet.

Ebben az oktatóanyagban megértjük a generikumok tömbökkel történő használatának kihívásait. Ezután létrehozunk egy példát egy általános tömbre.

Megvizsgáljuk azt is, hogy a Java API hol oldott meg hasonló problémát.

2. Az általános tömbök használatának szempontjai

Fontos különbség a tömbök és a generikusok között az, hogy miként hajtják végre a típusellenőrzést. Pontosabban, a tömbök futás közben tárolják és ellenőrzik a típusinformációkat. A generikusok azonban fordításkor ellenőrzik a típushibákat, és futás közben nem rendelkeznek típusinformációkkal.

A Java szintaxisa azt sugallja, hogy képesek lehetünk létrehozni egy új általános tömböt:

T [] elemek = új T [méret];

De ha ezt megkísérelnénk, fordítási hibát kapnánk.

Annak megértése érdekében, fontoljuk meg a következőket:

public T [] getArray (int méret) {T [] genericArray = új T [méret]; // tegyük fel, hogy ez megengedett return genericArray; }

Kötetlen általános típusként T elhatározza Tárgy, Futásidejű módszerünk a következő lesz:

public Object [] getArray (int size) {Object [] genericArray = new Object [size]; return genericArray; }

Ezután, ha meghívjuk a módszerünket, és az eredményt a-ban tároljuk Húr sor:

Karakterlánc [] myArray = getArray (5);

A kód jól összeáll, de futás közben nem sikerül az a-val ClassCastException. Ez azért van, mert most rendeltünk egy Tárgy[] a Húr[] referencia. Pontosabban, a fordító implicit leadása nem tud konvertálni Tárgy[] a kívánt típusunkhoz Húr[].

Noha nem tudjuk közvetlenül inicializálni az általános tömböket, mégis meg lehet valósítani az egyenértékű műveletet, ha a pontos információt a hívó kód biztosítja.

3. Általános tömb létrehozása

Példaként vegyünk egy korlátozott verem adatstruktúrát MyStack, ahol a kapacitás egy bizonyos méretre van rögzítve. Továbbá, mivel azt szeretnénk, hogy a verem bármilyen típusú működjön, az ésszerű megvalósítási választás egy általános tömb lenne.

Először hozzunk létre egy mezőt a verem elemeinek tárolására, amely egy általános típusú tömb E:

privát E [] elemek;

Másodszor adjunk hozzá egy konstruktort:

nyilvános MyStack (Class clazz, int kapacitás) {elemek = (E []) Array.newInstance (clazz, kapacitás); }

Figyelje meg, hogyan használunk java.lang.reflect.Array # newInstance hogy inicializáljuk az általános tömböt, amely két paramétert igényel. Az első paraméter meghatározza az új tömbben lévő objektum típusát. A második paraméter meghatározza, hogy mekkora teret kell létrehozni a tömb számára. Ennek eredményeként Tömb # newInstance típusú Tárgy, nekünk kell leadnunk E [] hogy létrehozzuk általános tömbünket.

Meg kell jegyeznünk egy típusparaméter elnevezésének konvencióját is clazz inkább mint osztály, ami egy fenntartott szó a Java-ban.

4. Figyelembe véve Tömb lista

4.1. Használata Tömb lista egy tömb helyén

Gyakran könnyebb általánosat használni Tömb lista általános tömb helyett. Lássuk, hogyan tudunk változtatni MyStack hogy használjon egy Tömb lista.

Először hozzunk létre egy mezőt az elemeink tárolására:

privát listaelemek;

Másodszor, veremkonstruktorunkban inicializálhatjuk a Tömb lista kezdeti kapacitással:

elemek = new ArrayList (kapacitás);

Ez egyszerűbbé teszi az osztályunkat, mivel nem kell reflexiót használnunk. Emellett a verem létrehozásakor nem kötelező az osztály szó szerinti betanítása. Végül, mivel beállíthatjuk az an kezdeti kapacitását Tömb lista, ugyanazokat az előnyöket kaphatjuk meg, mint egy tömb.

Ezért csak generikus tömböket kell felépítenünk ritka helyzetekben, vagy ha valamilyen tömböt igénylő külső könyvtárhoz kapcsolódunk.

4.2. Tömb lista Végrehajtás

Érdekes módon, Tömb lista maga generikus tömbök segítségével valósul meg. Nézzünk befelé Tömb lista hogy lássa, hogyan.

Először nézzük meg a listaelemek mezőt:

tranziens Object [] elementData;

Értesítés Tömb lista használ Tárgy mint elemtípus. Mivel általános típusunk futásig nem ismert, Tárgy bármilyen típusú szuperosztályként használják.

Érdemes megjegyezni, hogy majdnem az összes művelet Tömb lista használhatja ezt az általános tömböt, mivel egy módszer kivételével nem kell erősen beírt tömböt nyújtani a külvilág számára - array!

5. Tömb építése gyűjteményből

5.1. LinkedList példa

Nézzük meg, hogyan használhatunk általános tömböket a Java Collections API-ban, ahol egy új tömböt építünk egy gyűjteményből.

Először hozzunk létre egy újat LinkedList típusú érvvel Húr és tegyen elemeket hozzá:

Lista elemek = new LinkedList (); items.add ("első tétel"); items.add ("második tétel"); 

Másodszor, építsünk egy tömböt az imént hozzáadott elemekből:

Karakterlánc [] itemsAsArray = items.toArray (új String [0]);

A tömbünk felépítéséhez a Lista.array A metódushoz bemeneti tömb szükséges. Ezt a tömböt pusztán a típusinformációk megszerzésére használja a megfelelő típusú visszatérő tömb létrehozásához.

A fenti példánkban használtuk új karakterlánc [0] mint a bemeneti tömböt az eredmény felépítéséhez Húr sor.

5.2. LinkedList.toArray Végrehajtás

Kukkantsunk be LinkedList.toArray, hogy lássa, hogyan valósul meg a Java JDK-ban.

Először nézzük meg a metódus aláírását:

nyilvános T [] - Array (T [] a)

Másodszor, nézzük meg, hogyan jön létre egy új tömb, ha szükséges:

a = (T []) java.lang.reflect.Array.newInstance (a.getClass (). getComponentType (), méret);

Figyelje meg, hogyan használja Tömb # newInstance új tömb építéséhez, mint a verem korábbi példánkban. Figyelje meg a paraméter paraméterét is a a típus megadására szolgál Array # newInstance. Végül az eredmény Array # newInstance öntött T [] hozzon létre egy általános tömböt.

6. Következtetés

Ebben a cikkben először megvizsgáltuk a tömbök és a generikumok közötti különbségeket, majd követtünk egy példát egy általános tömb létrehozására. Aztán megmutattuk, hogyan használjuk az Tömb lista könnyebb lehet, mint egy általános tömb használata. Végül megvizsgáltuk egy általános tömb használatát a Gyűjtemények API-ban.

Mint mindig, a példa kód elérhető a GitHubon.