Vectori

Array-urile sau  vectorii reprezintă una dintre cele mai fundamentale structuri de date în programarea Java, oferind o metodă eficientă de a stoca și accesa colecții de elemente de același tip. Indiferent dacă ești la început în programare sau un dezvoltator experimentat, înțelegerea array-urilor este esențială pentru crearea de aplicații Java eficiente.

În acest articol vom explora în profunzime conceptul de array în Java, pornind de la noțiunile de bază până la tehnici avansate. Vom învăța cum să creăm array-uri, să le manipulăm, să înțelegem array-urile multidimensionale și să gestionăm dimensiunea acestora.

Ce este un Array în Java?

Un array în Java este o structură de date care poate stoca un număr fix de elemente de același tip. Acesta reprezintă o colecție ordonată de valori, fiecare valoare fiind identificată printr-un index numeric, începând de la 0.

Caracteristicile principale ale array-urilor în Java:

  1. Dimensiune fixă: Odată creat, dimensiunea unui array nu poate fi modificată.
  2. Stocare omogenă: Toate elementele unui array trebuie să fie de același tip de date.
  3. Indexare bazată pe zero: Primul element al unui array are indexul 0, al doilea are indexul 1, și așa mai departe.
  4. Stocare continuă în memorie: Elementele sunt stocate în locații consecutive de memorie.
  5. Acces direct la elemente: Permite accesul rapid la orice element prin specificarea indexului.

Exemplu simplu de array:

// Array de numere întregi
int[] numere = {5, 10, 15, 20, 25};

// Accesarea elementelor
System.out.println("Primul element: " + numere[0]); // Afișează 5
System.out.println("Al treilea element: " + numere[2]); // Afișează 15

Crearea unui Array în Java

În Java, există mai multe modalități de a crea un array. Să explorăm cele mai comune metode:

1. Declararea și inițializarea într-o singură linie

// Sintaxa: tip[] numeArray = {valoare1, valoare2, ...};
String[] fructe = {"măr", "banană", "portocală", "struguri"};

2. Declararea array-ului și alocarea de memorie

// Sintaxa: tip[] numeArray = new tip[dimensiune];
int[] numere = new int[5]; // Creează un array de 5 întregi, toate inițializate cu 0

// Atribuirea valorilor individual
numere[0] = 10;
numere[1] = 20;
numere[2] = 30;
numere[3] = 40;
numere[4] = 50;

3. Declararea și apoi inițializarea array-ului

// Declararea
double[] preturi;

// Inițializarea
preturi = new double[3];
preturi[0] = 19.99;
preturi[1] = 29.99;
preturi[2] = 39.99;

Valorile implicite pentru array-uri

Când creați un array folosind constructorul new, elementele sunt inițializate automat cu valori implicite:

  • Pentru tipuri numerice (int, long, double etc.): 0
  • Pentru boolean: false
  • Pentru tipuri de referință (obiecte): null
int[] numereIntregi = new int[3]; // Toate elementele sunt inițializate cu 0
boolean[] valoriBooleene = new boolean[3]; // Toate elementele sunt inițializate cu false
String[] texte = new String[3]; // Toate elementele sunt inițializate cu null

Copierea Vectorilor

Copierea array-urilor este o operație frecventă în programarea Java și poate fi realizată prin mai multe metode. Este important să înțelegem diferența dintre copierea superficială (shallow copy) și copierea profundă (deep copy).

1. Copierea manuală folosind bucla for

Cea mai simplă metodă conceptual este copierea element cu element:

int[] original = {1, 2, 3, 4, 5};
int[] copie = new int[original.length];

for (int i = 0; i < original.length; i++) {
    copie[i] = original[i];
}

Această metodă funcționează pentru toate tipurile de array-uri, dar poate fi ineficientă pentru array-uri mari.

2. Folosind metoda System.arraycopy()

Java oferă o metodă nativă pentru copierea array-urilor, care este mai eficientă:

int[] original = {1, 2, 3, 4, 5};
int[] copie = new int[original.length];

System.arraycopy(original, 0, copie, 0, original.length);

Parametrii metodei System.arraycopy() sunt:

  • Sursa (array-ul original)
  • Indexul de start din sursa
  • Destinația (array-ul copie)
  • Indexul de start din destinație
  • Numărul de elemente de copiat

3. Folosind metoda Arrays.copyOf()

Clasa Arrays din pachetul java.util oferă metode utile pentru manipularea array-urilor:

import java.util.Arrays;

int[] original = {1, 2, 3, 4, 5};
int[] copie = Arrays.copyOf(original, original.length);

Această metodă este nu doar ușor de utilizat, dar permite și redimensionarea array-ului în timpul copierii:

// Crearea unei copii mai mari
int[] copieExtinsa = Arrays.copyOf(original, original.length + 2);
// Rezultat: {1, 2, 3, 4, 5, 0, 0}

// Crearea unei copii mai mici
int[] copieRedusa = Arrays.copyOf(original, 3);
// Rezultat: {1, 2, 3}

4. Folosind metoda clone()

Toate array-urile din Java moștenesc metoda clone() de la clasa Object:

int[] original = {1, 2, 3, 4, 5};
int[] copie = original.clone();

Această metodă este simplă, dar are limitări pentru array-uri de obiecte complexe.

5. Copierea array-urilor multidimensionale

Pentru array-uri multidimensionale, metodele de mai sus realizează doar o "copiere superficială" - copiază referințele la sub-array-uri, nu sub-array-urile înseși:

import java.util.Arrays;

int[][] original = {{1, 2}, {3, 4}, {5, 6}};

// Folosind clone()
int[][] copie1 = original.clone();

// Folosind Arrays.copyOf()
int[][] copie2 = Arrays.copyOf(original, original.length);

Atât copie1 cât și copie2 vor conține referințe la aceleași sub-array-uri ca și original. Modificarea unui element dintr-un sub-array va afecta toate copiile.

6. Realizarea unei copii profunde pentru array-uri multidimensionale

Pentru a realiza o copie profundă a unui array multidimensional, trebuie să copiem fiecare sub-array individual:

int[][] original = {{1, 2}, {3, 4}, {5, 6}};
int[][] copieProfunda = new int[original.length][];

for (int i = 0; i < original.length; i++) {
    copieProfunda[i] = Arrays.copyOf(original[i], original[i].length);
}

Sau folosind Java 8 și Streams:

int[][] original = {{1, 2}, {3, 4}, {5, 6}};
int[][] copieProfunda = Arrays.stream(original)
                              .map(arr -> arr.clone())
                              .toArray(int[][]::new);

7. Considerații privind performanța

  • Pentru array-uri mici, toate metodele sunt suficient de rapide
  • Pentru array-uri mari, System.arraycopy() este de obicei cea mai eficientă metodă
  • Pentru utilizare simplă, Arrays.copyOf() și clone() oferă un bun echilibru între ușurința de utilizare și performanță

8. Copierea array-urilor de obiecte

Când copiați array-uri de obiecte, toate metodele prezentate mai sus realizează doar copii superficiale - copiază referințele la obiecte, nu obiectele în sine:

Person[] persoane = {new Person("Ana"), new Person("Mihai")};
Person[] copie = persoane.clone();

// Modificarea unui obiect va afecta ambele array-uri
persoane[0].setName("Ana Maria");
System.out.println(copie[0].getName()); // Va afișa "Ana Maria"

Pentru a realiza o copie profundă a unui array de obiecte, trebuie ca clasa obiectelor să implementeze interfața Cloneable sau să ofere propriul mecanism de copiere:

Person[] persoane = {new Person("Ana"), new Person("Mihai")};
Person[] copieProfunda = new Person[persoane.length];

for (int i = 0; i < persoane.length; i++) {
    copieProfunda[i] = persoane[i].clone(); // Presupunând că Person implementează Cloneable
}

Array-uri Multidimensionale în Java

Java suportă array-uri multidimensionale, care sunt de fapt array-uri de array-uri. Cele mai comune sunt array-urile bidimensionale, care pot fi vizualizate ca matrice cu rânduri și coloane.

Declararea și inițializarea array-urilor bidimensionale

// Declararea și inițializarea într-o singură linie
int[][] matriceA = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// Declararea și alocarea de memorie
int[][] matriceB = new int[3][3]; // O matrice 3x3 de întregi

// Atribuirea valorilor individual
matriceB[0][0] = 1;
matriceB[0][1] = 2;
// ... și așa mai departe

Array-uri neregulate (jagged arrays)

În Java, rândurile unui array multidimensional pot avea lungimi diferite:

int[][] arrayNeregulat = {
    {1, 2, 3},
    {4, 5},
    {6, 7, 8, 9}
};

// Declararea și alocarea pentru un array neregulat
int[][] altArrayNeregulat = new int[3][];
altArrayNeregulat[0] = new int[3];
altArrayNeregulat[1] = new int[2];
altArrayNeregulat[2] = new int[4];

Iterarea prin array-uri multidimensionale

// Iterarea printr-un array bidimensional
for (int i = 0; i < matriceA.length; i++) {
    for (int j = 0; j < matriceA[i].length; j++) {
        System.out.print(matriceA[i][j] + " ");
    }
    System.out.println(); // Trecem la următorul rând
}

// Folosind bucla for-each (mai elegantă)
for (int[] rand : matriceA) {
    for (int element : rand) {
        System.out.print(element + " ");
    }
    System.out.println();
}

Array-uri tridimensionale și de dimensiuni superioare

Java suportă și array-uri de dimensiuni superioare, deși acestea sunt mai rar utilizate:

// Array tridimensional
int[][][] cub = new int[3][3][3];

// Atribuirea unei valori
cub[0][1][2] = 42;

// Iterarea printr-un array tridimensional
for (int i = 0; i < cub.length; i++) {
    for (int j = 0; j < cub[i].length; j++) {
        for (int k = 0; k < cub[i][j].length; k++) {
            System.out.print(cub[i][j][k] + " ");
        }
        System.out.println();
    }
    System.out.println();
}

Dimensiunea unui Vector în Java

Managementul dimensiunii este un aspect important al lucrului cu array-uri în Java. Fiind structuri de date cu dimensiune fixă, este esențial să înțelegem cum să determinăm și să utilizăm eficient informațiile despre dimensiune.

Obținerea dimensiunii unui array

În Java, puteți determina dimensiunea (numărul de elemente) a unui array folosind proprietatea length:

int[] numere = {10, 20, 30, 40, 50};
int dimensiune = numere.length; // dimensiune = 5

System.out.println("Array-ul conține " + dimensiune + " elemente.");

Dimensiunea array-urilor multidimensionale

Pentru array-uri multidimensionale, proprietatea length oferă numărul de elemente de pe primul nivel (numărul de rânduri pentru un array bidimensional):

int[][] matrice = {
    {1, 2, 3},
    {4, 5, 6}
};

int numarRanduri = matrice.length; // 2
int numarColoanePrimulRand = matrice[0].length; // 3

System.out.println("Matricea are " + numarRanduri + " rânduri și primul rând are " + numarColoanePrimulRand + " coloane.");

Limitările dimensiunii fixe și soluții

Dimensiunea fixă a array-urilor poate fi o limitare în aplicațiile care necesită colecții dinamice. Iată câteva soluții pentru această problemă:

1. Crearea unui array nou cu dimensiune mai mare

int[] arrayVechi = {1, 2, 3};
int[] arrayNou = new int[5]; // Array nou cu dimensiune mai mare

// Copierea elementelor
for (int i = 0; i < arrayVechi.length; i++) {
    arrayNou[i] = arrayVechi[i];
}

// Adăugarea de noi elemente
arrayNou[3] = 4;
arrayNou[4] = 5;

2. Utilizarea metodei System.arraycopy()

int[] arrayVechi = {1, 2, 3};
int[] arrayNou = new int[5];

System.arraycopy(arrayVechi, 0, arrayNou, 0, arrayVechi.length);

// Acum arrayNou conține: {1, 2, 3, 0, 0}
arrayNou[3] = 4;
arrayNou[4] = 5;
// arrayNou devine: {1, 2, 3, 4, 5}

3. Utilizarea clasei Arrays

import java.util.Arrays;

int[] arrayVechi = {1, 2, 3};
int[] arrayNou = Arrays.copyOf(arrayVechi, 5);

// Adăugarea de noi elemente
arrayNou[3] = 4;
arrayNou[4] = 5;

4. Utilizarea colecțiilor dinamice

Pentru aplicații care necesită colecții de dimensiuni variabile, Java oferă alternative precum ArrayList, LinkedList sau alte implementări ale interfeței Collection:

import java.util.ArrayList;

ArrayList<Integer> listaNumere = new ArrayList<>();
listaNumere.add(1);
listaNumere.add(2);
listaNumere.add(3);

// Adăugarea de noi elemente
listaNumere.add(4);
listaNumere.add(5);

System.out.println("Lista conține " + listaNumere.size() + " elemente.");

Operații Comune cu Array-uri în Java

Sortarea unui array

import java.util.Arrays;

int[] numere = {5, 2, 8, 1, 9};
Arrays.sort(numere);
// Acum numere conține: {1, 2, 5, 8, 9}

Căutarea în array

import java.util.Arrays;

int[] numere = {10, 20, 30, 40, 50};
int index = Arrays.binarySearch(numere, 30); // Returnează 2 (indexul elementului 30)

Verificarea egalității array-urilor

import java.util.Arrays;

int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
int[] array3 = {3, 2, 1};

boolean esteEgal1si2 = Arrays.equals(array1, array2); // true
boolean esteEgal1si3 = Arrays.equals(array1, array3); // false

Umplerea unui array cu o valoare specifică

import java.util.Arrays;

int[] numere = new int[5];
Arrays.fill(numere, 42);
// Acum numere conține: {42, 42, 42, 42, 42}

Bune Practici pentru Utilizarea Array-urilor

  1. Verificați întotdeauna limitele: Accesarea unui element în afara limitelor array-ului va genera o excepție ArrayIndexOutOfBoundsException.
int[] numere = {1, 2, 3};
// Bună practică: verificarea înainte de accesare
if (index >= 0 && index < numere.length) {
    System.out.println(numere[index]);
}
  1. Utilizați bucla for-each când este posibil: Este mai puțin predispusă la erori și mai ușor de citit.
int[] numere = {1, 2, 3, 4, 5};
// Bucla for-each
for (int numar : numere) {
    System.out.println(numar);
}
  1. Alegeți colecțiile potrivite: Folosiți array-uri pentru colecții de dimensiune fixă și clasele din pachetul java.util (precum ArrayList) pentru colecții dinamice.

  2. Inițializați array-urile corespunzător: Asigurați-vă că elementele array-ului sunt inițializate înainte de a fi utilizate.

Array-urile sunt unelte esențiale în programarea Java, oferind o metodă eficientă de a lucra cu colecții de date de același tip. Deși au limitări în ceea ce privește dimensiunea fixă, înțelegerea aprofundată a modului lor de funcționare vă va permite să creați aplicații Java mai eficiente și mai robuste.

De la array-uri unidimensionale simple la structuri multidimensionale complexe, cunoașterea acestui tip fundamental de date vă va oferi baza necesară pentru a avansa în programarea Java. Pe măsură ce vă dezvoltați abilitățile, veți descoperi și alte structuri de date și colecții care completează array-urile, oferind soluții pentru o gamă largă de probleme de programare.

Experimentați cu exemplele de cod prezentate în acest articol pentru a vă consolida înțelegerea și nu ezitați să explorați biblioteca standard Java pentru a descoperi metode suplimentare de lucru cu array-uri.

Share on


Echipa conspecte.com, crede cu adevărat că studenții care studiază devin următoarea generație de aventurieri și lideri cu gândire globală - și dorim cât mai mulți dintre voi să o facă!