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, 6Uguaglianza
== 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)); // truePer 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); // 3Se 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;.
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 arrayclone() 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
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.