Tömb másolása Java-ban
1. Áttekintés
Ebben a rövid cikkben különféle tömbmásolási módszereket tárgyalunk a Java-ban. A tömb példánya triviális feladatnak tűnhet, de ha nem gondosan végezzük, váratlan eredményeket és program viselkedést okozhat.
2. A Rendszer Osztály
Kezdjük a Java alapkönyvtárral - System.arrayCopy (); ez egy tömböt átmásol egy forrás tömbből egy cél tömbbe, kezdve a másolási műveletet a forrás pozíciótól a cél pozícióig a megadott hosszúságig.
A céltömbbe másolt elemek száma megegyezik a megadott hosszúsággal. Könnyű módot kínál egy tömb alsorrendjének másolására egy másikba.
Ha a tömb egyik argumentuma az nulla, dob egy NullPointerException és ha az egész argumentum bármelyike negatív vagy tartományon kívül esik, akkor egy IndexOutOfBoundException.
Nézzünk meg egy példát egy teljes tömb másolására egy másikra a java.util.System osztály:
int [] tömb = {23, 43, 55}; int [] copiedArray = új int [3]; System.arraycopy (tömb, 0, copiedArray, 0, 3);
A módszer érvei a következők; forrás tömb, a forrás tömbből másolandó kiinduló helyzet, cél tömb, a cél tömb kiindulási helye és a másolandó elemek száma.
Vessen egy pillantást egy másik példára, amely egy részsorrend másolását mutatja egy forrás tömbből a célba:
int [] tömb = {23, 43, 55, 12, 65, 88, 92}; int [] copiedArray = új int [3]; System.arraycopy (tömb, 2, copiedArray, 0, 3);
assertTrue (3 == copiedArray.length); assertTrue (copiedArray [0] == tömb [2]); assertTrue (copiedArray [1] == tömb [3]); assertTrue (copiedArray [2] == tömb [4]);
3. Az Tömbök Osztály
A Tömbök osztály több túlterhelt módszert is kínál egy tömb másolásához. Belsőleg ugyanazt a megközelítést alkalmazza, amelyet a Rendszer osztály, amelyet korábban láttunk. Főleg két módszert kínál, másolata(…) és copyRangeOf (…).
Nézzük meg másolata első:
int [] tömb = {23, 43, 55, 12}; int newLength = tömb.hossz; int [] copiedArray = Tömbök.copyOf (tömb, newLength);
Fontos megjegyezni Tömbök osztály használ Math.min (…) a forrás tömbhossz minimumának és az új hosszparaméter értékének kiválasztásához a kapott tömb méretének meghatározásához.
Arrays.copyOfRange () 2 paramétert vesz fel,tól től' és „nak nek' a forrás tömb paraméter mellett. A kapott tömb tartalmazza atól től' index, de a 'nak nek' index kizárt. Lássunk egy példát:
int [] tömb = {23, 43, 55, 12, 65, 88, 92}; int [] copiedArray = Tömbök.copyOfRange (tömb, 1, 4);
assertTrue (3 == copiedArray.length); assertTrue (copiedArray [0] == tömb [1]); assertTrue (copiedArray [1] == tömb [2]); assertTrue (copiedArray [2] == tömb [3]);
Mindkét módszer sekély példányt készítsen objektumok, ha nem primitív objektumtípusok tömbjére alkalmazzák. Lássunk egy példát a tesztesetre:
Alkalmazott [] copiedArray = Arrays.copyOf (alkalmazottak, alkalmazottak.hossz); alkalmazottak [0] .setName (alkalmazottak [0] .getName () + "_Change"); assertArrayEquals (copiedArray, tömb);
Mivel az eredmény sekély másolat - az eredeti tömb elemének alkalmazott nevében bekövetkezett változás megváltoztatta a másolási tömböt.
Tehát - ha a nem primitív típusok mély másolatát akarjuk elvégezni - a következő szakaszokban leírt további lehetőségek mellett dönthetünk.
4. Array Copy With Object.clone ()
Object.clone () -től öröklődik Tárgy osztály egy tömbben.
Először másoljunk egy primitív tömböt klón módszerrel:
int [] tömb = {23, 43, 55, 12}; int [] copiedArray = tömb.klón ();
És bizonyíték arra, hogy működik:
assertArrayEquals (copiedArray, tömb); tömb [0] = 9; assertTrue (copiedArray [0]! = tömb [0]);
A fenti példa azt mutatja, hogy a klónozás után ugyanaz a tartalom van, de különböző hivatkozásokkal rendelkeznek, így bármelyikben bekövetkező változás nem érinti a másikat.
Másrészt, ha nem primitív típusú tömböt klónozunk ugyanazon módszerrel, akkor az eredmények eltérőek lesznek.
Teremt sekély példány a nem primitív típusú tömb elemek közül, még akkor is, ha a zárt objektum osztálya végrehajtja a Klónozható interfész és felülírja a klón () módszer a Tárgy osztály.
Nézzünk meg egy példát:
public class Address implementálja a Cloneable {// ... @Orride protected Object clone () dobja a CloneNotSupportedException {super.clone (); Cím címe = új cím (); address.setCity (this.city); visszaszállítási cím; }}
Tesztelhetjük megvalósításunkat egy új címtömb létrehozásával és a mi meghívásunkkal klón () módszer:
Cím [] címek = createAddressArray (); Cím [] copiedArray = címek.klón (); címek [0] .setCity (címek [0] .getCity () + "_Changed");
assertArrayEquals (copiedArray, címek);
Ez a példa azt mutatja, hogy az eredeti vagy a másolt tömb bármilyen változása a másik változását okozhatja akkor is, ha a zárt objektumokat Klónozható.
5. A Folyam API
Kiderült, hogy a Stream API-t is használhatjuk tömbök másolásához. Nézzünk meg egy példát:
Karakterlánc [] strArray = {"narancs", "piros", "zöld" "}; String [] copiedArray = tömbök.stream (strArray) .toArray (karakterlánc [] :: új);
A nem primitív típusok esetében az objektumok sekély másolatát is elkészíti. További információkért Java 8 adatfolyamok, itt kezdheti.
6. Külső könyvtárak
Apache Commons 3 nevű segédprogramot kínál SerializationUtils amely biztosítja a klón (…) módszer. Nagyon hasznos, ha egy nem primitív típusú tömb mély másolatát kell készítenünk. Innen letölthető, és Maven-függősége:
org.apache.commons commons-lang3 3.5
Vessünk egy pillantást egy tesztesetre:
public class Alkalmazott megvalósítja a Serializálható {// mezők // szabványos getterek és beállítók} Employee [] alkalmazottak = createEmployeesArray (); Alkalmazott [] copiedArray = SerializationUtils.clone (alkalmazottak);
alkalmazottak [0] .setName (alkalmazottak [0] .getName () + "_Changed"); assertFalse (copyiedArray [0] .getName (). egyenlő (alkalmazottak [0] .getName ()));
Ez az osztály megköveteli, hogy minden objektumnak végre kell hajtania a Sorosítható felület. A teljesítmény szempontjából lassabban másolhatók, mint az objektumgrafikonunkban található egyes objektumokhoz kézzel írott klón módszerek.
7. Következtetés
Ebben az oktatóanyagban megvizsgáltuk a tömb Java-ba másolásának különféle lehetőségeit.
Az alkalmazandó módszer elsősorban a pontos forgatókönyvtől függ. Amíg egy primitív tömböt használunk, használhatjuk a Rendszer és Tömbök osztályok. A teljesítményben nem lehet különbség.
Nem primitív típusok esetén, ha egy tömb mély másolatát kell készítenünk, használhatjuk a SerializationUtils vagy kifejezetten klónozási módszereket adjunk osztályainkhoz.
És mint mindig, az ebben a cikkben bemutatott példák a GitHubon keresztül elérhetők.