Java/Array: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
cambio avanzamento al 50% |
riorganizzo, aggiungo, taglio |
||
Riga 1:
{{Java/Prima parte}}
In Java, gli array sono [[Java/Oggetti|oggetti]]. Ogni array è dotato di un numero fisso di ''celle'', dette anche ''slot'' (in inglese), ognuna delle quali è identificata da un intero positivo, chiamato "indice". Il numero esatto di ''slot'' viene indicato al momento della allocazione dell'array in memoria.
Il capito dedicato agli array nella seconda edizione delle specifiche di linguaggio è il [http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html capitolo 10].
__TOC__
== Dichiarazione ==
Il tipo di un array è identificato dal nome del ''component type'', seguito da una coppia di parentesi quadre. Esempi:
*<tt>int[]</tt> indica il tipo <tt>array di int</tt>
*<tt>Object[]</tt> indica il tipo <tt>array di Object</tt>
*<tt>int[][]</tt> indica il tipo array il cui ''component type'' è <tt>int[]</tt>, quindi, in definitiva, indica il tipo <tt>array di array di int</tt>
Il tipo di un array non include '''mai''' il numero degli elementi (a differenza di quanto avviene in C e in C++).
== Creazione e distruzione ==
; Con inizializzazione al valore di default
È possibile allocare un array in memoria servendosi della parola-chiave <tt>new</tt>:
:<tt>int[] i = new int[10];</tt>
Il numero di elementi tra parentesi quadre è obbligatorio.
Tutte le celle dell'array sono automaticamente [[Java/Oggetti#Inizializzazione dei campi|inizializzate]] con il valore di default del ''component type'' corrispondente. Nell'esempio appena mostrato, tutti gli ''slot'' dell'array referenziato dalla variabile <tt>i</tt> valgono inizialmente <tt>0</tt>.
Ad esempio, l'istruzione <code>new byte[1024]</code> crea un array di 1024 slot inizializzati al valore 0; oppure <code>new Object[1024]</code> crea un array di 1024 celle e assegna loro il valore ''null''. Si noti che questo meccanismo è diverso da quello che si trova in altri linguaggi, come il C (in cui le celle dell'array hanno inizialmente valori casuali o imprevedibili), ed è lo stesso meccanismo che in Java entra in atto quando si crea un oggetto di qualunque altro tipo.
; Indicando i singoli elementi
È disponibile un costrutto alternativo che permette di indicare direttamente i valori delle singole celle:
<source lang="Java">
Line 62 ⟶ 41:
</source>
<source lang="Java">
int[] numeri = { -1, 0, 0 };
Line 74 ⟶ 53:
perché la dichiarazione e l'inizializzazione della variabile <tt>numeri</tt> ora sono due istruzioni diverse.
; Deallocazione
A differenza di quanto avviene in C++, gli array '''non''' vengono distrutti esplicitamente, in quanto il Java è dotato di [[w:it:garbage collector|garbage collector]].
== Tipi array ==
I tipi array sono tipi riferimento.
Come per tutti i tipi riferimento, il valore di default per un campo di tipo array non inizializzato è <tt>null</tt>:
<source lang="Java">
class C {
private final int[] array;
public static void main(String[] args) {
C c = new C();
for(int i = 0; i < array.length; i++) {
System.out.println(i); // stampa a video il valore 0
}
}
}
</source>
=== Gerarchia delle classi ===
È sempre possibile convertire un tipo array verso il tipo <tt>Object</tt> tramite cast implicito, in quanto tutti gli array sono oggetti.
In aggiunta, tutti gli array possono essere convertiti verso i tipi [http://download.oracle.com/javase/6/docs/api/java/lang/Cloneable.html java.lang.Cloneable] e [http://download.oracle.com/javase/6/docs/api/java/io/Serializable.html java.io.Serializable]. In particolare,
*gli array supportano il metodo <code>[http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#clone() clone()]</code>;
*è possibile serializzare gli array come qualunque altro oggetto:
<source lang="Java">
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("un_file.ser"));
oos.writeObject(unArray);
</source>
=== Gerarchia fra tipi array ===
Il tipo di un array creato con <tt>new T[...]</tt> è <tt>T[]</tt>. L'array può essere convertito verso qualunque tipo <code>S[]</tt> dove <tt>S</tt> è un supertipo di <tt>T</tt>.
Questo significa che tutti gli array di oggetti possono essere convertiti verso <code>Object[]</code>.
== Membri di un array ==
; Celle
Le singole celle dell'array sono considerate come dei campi, e sono identificate apponendo una coppia di parentesi quadre ad un'espressione il cui ''compile-time type'' sia un tipo array, e inserendo fra queste parentesi un'espressione il cui ''compile-time type'' sia convertibile verso il tipo <tt>int</tt> tramite cast implicito.
Ad esempio:
:<tt>System.out.println(i[0]);</tt> stampa a video il valore della prima cella dell'array referenziato dalla variabile <tt>i</tt>.
:<tt>i[0] = 5;</tt> assegna il valore intero <tt>5</tt> alla prima cella dell'array.
L'indice della prima cella è sempre <tt>0</tt><ref>Si dice che gli indici sono <tt>0-based</tt>. In altri linguaggi, gli indici sono sempre <tt>1-based</tt> o possono essere scelti arbitrariamente.</ref> e, pertanto, l'indice dell'ultima cella è sempre <tt>n - 1</tt>, dove <tt>n</tt> è il numero di celle totali.
; Lunghezza
Il numero di celle è restituito dal campo <tt>length</tt>. Questo si comporta come un campo <tt>final int</tt>.
; Clonazione
Gli array esibiscono un metodo pubblico <tt>[http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#clone() clone()]</tt>.
== ArrayIndexOutOfBoundsException ==
A differenza di quanto avviene in altri linguaggi (come il C) in Java non è permesso leggere o scrivere al di fuori della memoria che è stata allocata per l'array. In altre parole, in Java non è possibile accedere ad una cella che ha un indice inferiore all'indice minimo (che è sempre 0) o superiore all'indice massimo (che è sempre pari ad <code>array.length - 1</code>).
Se si tenta di compiere una operazione del genere, la macchina virtuale lancerà una eccezione a tempo di esecuzione:
<source lang="Java">
int[] array = new int[3];
array[-1] = 10; // ops...
</source>
L'eccezione lanciata è sempre di tipo [http://download.oracle.com/javase/6/docs/api/java/lang/ArrayIndexOutOfBoundsException.html ArrayIndexOutOfBoundsException]. Il [[Java/Gestione delle eccezioni|meccanismo che entra in gioco]] quando si verifica un caso del genere è del tutto analogo a quello che si verifica quando viene lanciata un'eccezione di altro tipo.
== Utilizzi tipici ==
=== Iterazione classica ===
<source lang="Java">
// Riempie l'array con i numeri progressivi da 0 ad array.length:
Line 93 ⟶ 134:
*quindi, la condizione da applicare al ciclo è <code>i <= array.length-1</code>, oppure, equivalentemente, <code>i < array.length</code>.
Molti programmatori alle prime armi con il Java commettono il seguente errore:
<source lang="Java">
Line 99 ⟶ 140:
... // istruzioni
</source>
Questo ciclo fa sì che le istruzioni che costituiscono il corpo del ''for'' siano eseguite una volta in più rispetto a quanto avviene nel codice precedente, perché il corpo viene eseguito anche per <code>i = array.length</code>, cioè quando ''i'' rappresenta un indice che non ha una cella corrispondente nell'array. Un simile errore viene scoperto solo a ''run-time'', quando il programma [[#ArrayIndexOutOfBoundsException|genera una ArrayIndexOutOfBoundsException]] non prevista
=== For each ===
A volte si può usare un costrutto alternativo:
<source lang="Java">
Line 117 ⟶ 159:
ovvero scorre l'array, dall'indice 0 all'indice <code>array.length - 1</code>, assegnando automaticamente il valore <code>array[i]</code> alla variabile <code>slot</code>, e ad ogni ciclo esegue l'istruzione <code>System.out.println(slot)</code>.
== Array e collezioni ==
Le librerie standard della piattaforma Java forniscono un insieme di classi e interfacce che definiscono collezioni, e che si chiama ''Java Collections Framework''.
=== Conversione ===
; Da collezione ad array
Invocare sulla collezione uno dei due metodi <tt>[http://download.oracle.com/javase/6/docs/api/java/util/Collection.html toArray()]</tt>.
'''''Nota''': questo metodo restituisce una '''copia''' degli elementi della collezione: se quest'ultima viene modificata in seguito, le modifiche non interesseranno anche l'array.''
Invocare il metodo <tt>[http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T...) java.util.Arrays.asList()]</tt>.
'''''Nota''': questo metodo restituisce una List che opera '''sull'array''' passato come argomento: se quest'ultimo verrà modificato in seguito, le modifiche potrebbero ripercuotersi sulla List.''
== Array e Collection ==
{{vedi anche|Java/Collections{{!}}Java Collections Framework}}
Un array
La scelta fra un tipo array e una List (o altra Collection) è arbitraria e lasciata al programmatore.
Line 161 ⟶ 184:
Nella scelta si deve tenere conto anche del fatto che List è un'interfaccia, quindi un client può implementare una propria versione di List che esegua codice personalizzato in risposta all'invocazione di alcuni dei suoi metodi. Ad esempio, un'implementazione può gestire una coda di [http://download.oracle.com/javase/6/docs/api/java/util/EventListener.html java.util.EventListener]s notificati ogni volta che la lista subisce un cambiamento; oppure si possono adottare alcune delle implementazioni fornite dalla classe [http://download.oracle.com/javase/6/docs/api/java/util/Collections.html java.util.Collections]; ecc. Insomma, lo strato di astrazione fornito dall'interfaccia List permette di riutilizzare il codice, se in futuro dovessero presentarsi nuove esigenze da parte di qualche client, sfruttando un "punto di accesso" tramite il quale si possono inserire delle implementazioni personalizzate della propria lista con una modifica minima al codice originale<ref>Anzi, se il codice è stato scritto bene, non è necessario modificare il codice originale, ma solo il client, e anche in quest'ultimo, nel migliore dei casi, è sufficiente modificare una sola riga di codice</ref>. Questo non è possibile se si usano gli arrays.
== Note ==
|