W3docs

Operazioni comuni sugli array in Java

Esegui operazioni comuni sugli array in Java: lunghezza, copia, riempimento, ricerca e conversione in List.

Gli array di per sé non hanno molti metodi. L'oggetto array espone un campo (length) e un metodo (clone()). Tutto il resto — stampa, riempimento, ricerca, confronto — si trova nella classe di utilità java.util.Arrays, che approfondiremo nel prossimo capitolo. Questo capitolo è una panoramica delle operazioni quotidiane: cosa fanno e quale chiamata utilizzare.

Questa pagina tratta la lettura della dimensione, la stampa, il riempimento, il confronto, la ricerca, la copia e la conversione di un array in una List. Per ogni operazione esiste di solito una chiamata idiomatica — l'obiettivo è riconoscere qual è quella giusta.

Lunghezza

int[] data = {3, 1, 4, 1, 5, 9, 2, 6};
System.out.println(data.length);   // 8

È un campo, non un metodo — senza parentesi. length è fisso una volta creato l'array; per "espandere" un array se ne alloca uno nuovo e si copia (vedi Copia più avanti). Nota che length è un campo degli array, mentre String e le collezioni come List usano un metodo length() o size() — una fonte comune di confusione.

Stampa di un array

System.out.println(arr) stampa qualcosa come [I@1540e19d — il nome della classe e l'hash. Quasi mai è quello che si vuole. Usa Arrays.toString:

import java.util.Arrays;

int[] data = {3, 1, 4, 1, 5};
System.out.println(Arrays.toString(data));   // [3, 1, 4, 1, 5]

Per gli array bidimensionali usa Arrays.deepToString:

int[][] grid = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(grid));   // [[1, 2], [3, 4]]

Riempimento

Per impostare ogni elemento allo stesso valore:

int[] zeros = new int[5];
Arrays.fill(zeros, 7);              // {7, 7, 7, 7, 7}

La forma con intervallo riempie solo [fromIndex, toIndex):

int[] data = new int[10];
Arrays.fill(data, 3, 7, 1);         // ones in positions 3, 4, 5, 6

Uguaglianza

== sugli array confronta i riferimenti, non il contenuto. Per l'uguaglianza elemento per elemento, usa Arrays.equals:

int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b);                    // false (different objects)
System.out.println(Arrays.equals(a, b));       // true

Per gli array annidati, usa Arrays.deepEquals. Per la semantica null-safe, entrambi i metodi considerano null == null come true.

Ricerca

Una scansione lineare con un ciclo classico va bene per array piccoli o con ordine sconosciuto:

int[] data = {7, 3, 9, 1, 5};
int target = 9;
int found = -1;
for (int i = 0; i < data.length; i++) {
  if (data[i] == target) { found = i; break; }
}

Per un array ordinato, Arrays.binarySearch è O(log n):

int[] sorted = {1, 3, 5, 7, 9};
int idx = Arrays.binarySearch(sorted, 7);   // 3

Se il valore non è presente, binarySearch restituisce un numero negativo che codifica dove andrebbe: -(insertionPoint) - 1. Quindi un risultato di -8 significa "non trovato, appartiene all'indice 7." Per ricavare il punto di inserimento: int insert = -(result) - 1;.

Informazione
Arrays.binarySearch funziona solo su un array ordinato. Con input non ordinato non lancia un'eccezione — restituisce silenziosamente un risultato errato o imprevedibile. Ordina prima (Arrays.sort), oppure usa una scansione lineare quando l'array non è ordinato.

Copia

Per ottenere un nuovo array con lo stesso contenuto:

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

Per ridimensionare durante la copia — riempie con valori predefiniti se più lungo, tronca se più corto:

int[] longer  = Arrays.copyOf(data, 8);    // {1, 2, 3, 4, 5, 0, 0, 0}
int[] shorter = Arrays.copyOf(data, 3);    // {1, 2, 3}

Per copiare una porzione:

int[] middle = Arrays.copyOfRange(data, 1, 4);   // {2, 3, 4}

from è incluso, to è escluso — la consueta convenzione Java degli intervalli semi-aperti.

L'unico metodo di copia che appartiene all'array stesso è clone():

int[] data = {1, 2, 3};
int[] dup  = data.clone();          // {1, 2, 3}, a separate array

clone() esegue una copia superficiale: per un array di oggetti (o un array 2D, che è un array di array) i riferimenti interni sono condivisi, non duplicati. Ulteriori approfondimenti sulla copia — inclusi System.arraycopy e le copie profonde — si trovano nel capitolo dedicato Copia di array.

Conversione in List

Arrays.asList(...) avvolge un array (di riferimenti) come una List a dimensione fissa:

String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr);

È a dimensione fissa: add/remove lanciano UnsupportedOperationException, ma è possibile usare list.set(...). Nota che asList non funziona con gli array primitivi come ci si aspetterebbe — Arrays.asList(new int[]{1, 2, 3}) produce una List<int[]> di lunghezza 1, non una List<Integer>. Per i primitivi, usa gli stream:

import java.util.stream.IntStream;

int[] nums = {1, 2, 3};
List<Integer> boxed = IntStream.of(nums).boxed().toList();

Hashing

Arrays.hashCode(arr) produce un hash basato sul contenuto utilizzabile nelle implementazioni di equals/hashCode di una classe contenitrice:

int[] data = {1, 2, 3};
int h = Arrays.hashCode(data);

Per gli array annidati, usa Arrays.deepHashCode.

Esempio pratico

java— editable, runs on the server

Cosa fare dopo

I metodi che hai appena usato — toString, fill, equals, copyOf, binarySearch, sort — si trovano tutti nella stessa classe: java.util.Arrays. Il prossimo capitolo analizza sistematicamente la classe di utilità Arrays, includendo gli aspetti che qui abbiamo tralasciato.

Esercizi

Pratica
Cosa stampa System.out.println(arr) per un int[]?
Cosa stampa System.out.println(arr) per un int[]?
Was this page helpful?