Tutorial Java – #4.2 Cum se copiaza in Java elementele unui vector in alt vector

2 comments - This post in english

In acest post sunt descrise modalitatile prin care se poate copia un vector in alt vector, la nivel de valori. Nu trebuie uitat faptul ca vectorii reprezinta in Java obiecte (Tutorial Java 6 – #4 Vectori) ceea ce inseamna ca numele vectorului, variabila prin care gestionam colectia de valori, este o referinta, un pointer, ce contine adresa primului element din vector.

Pornind de la aceasta ipoteza, este important sa intelegem ca elementele unui vector NU SE COPIAZA ASA:

         //vector initial
        int[] oldArray = {1,2,3,4,5};
        //vector nou
        int[] newArray;
 
        //copiere la nivel de referinta
        newArray = oldArray;
 
        //afisare valoare prin a 2-a referinta
        //afiseaza valoarea 3
        System.out.println(newArray[2]);

Sunt rare momentele in care este dorita o “copiere” de acest gen, insa de cele mai multe ori este o greseala. In final, elementele vectorului initial NU au fost copiate, ci valoarea primei referinte oldArray a fost copiata in noua referinta, newArray. La nivel de memorie, figura urmatoare este sugestiva, va exista o singura colectie de valori si doua referinte ce gestioneaza acea colectie.

Array Shallow Copy in Java

Array Shallow Copy in Java

Chiar daca pare o copiere de valori reusita, testul afisarii unei valori dovedeste asta, problema este ca orice modificare a valorilor prin intermediul unei referinte va fi vizibila si prin intermediul celei de-a doua referinte.

        //modific o valoare prin prima referinta
        oldArray[0] = 100;
        //afisez prima valoarea prin a 2-a referinta
        System.out.println(newArray[0]);    //afiseaza tot 100

Si daca aceasta situatie nu este ceea ce ne-am dorit, atunci va fi greu de gestionat deoarece este o eroare logica care nu va genera exceptii la compilare sau la executie.

Ceea ce am vazut poarta denumirea de copiere superficiala (shallow copy) deoarece are loc doar la nivel de referinta. Ceea ce ne intereseaza de cele mai multe ori este o copiere de continut (deep copy).

In java, pentru a copia elementele unui vector in alt vector exista 2 posibilitati:

  1. o implementarea proprie a unui algoritm de copiere;
  2. utilizarea unei functii din API.

Pentru prima abordare, copierea inseamna:

  1. definirea unui nou vector;
  2. alocarea de spatiu pentru noul vector;
  3. copierea valorilor din vectorul initial:
          //vector initial
        int[] oldArray = {1,2,3,4,5};
        //definire vector nou + alocare spatiu
        int[] newArray = new int[oldArray.length];
 
        //copiere valori
        for(int i =0;i < oldArray.length;i++)
            newArray[i] = oldArray[i];

A doua solutie se bazeaza pe utilizarea functiei arraycopy din libraria System cu header-ul:

System.arraycopy( source, sourceStart, destination, destStart, length );
  1. definirea unui nou vector;
  2. alocarea de spatiu pentru noul vector;
  3. copierea valorilor din vectorul initial cu functia arraycopy :
          //vector initial
        int[] oldArray = {1,2,3,4,5};
        //definire vector nou + alocare spatiu
        int[] newArray = new int[oldArray.length];
 
        //copiere valori
        System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);

Alte topicuri care fac parte din acest tutorial Java 6 sunt accesibile prin Tutorial Java 6 – Continut.

,