2009-04-06 29 views
5

In questo codice, perché il mio array non è inizializzato come lo voglio? Il ciclo for-each non è progettato per farlo, o sto semplicemente non lo uso correttamente?Perché questo ciclo non funziona?

int[] array = new int[5]; 

    //initialise array -> Doesn't work! Array still full of 0's 
    for(int i : array) 
     i = 24; 
+0

L'altra domanda non dovrebbe essere un duplicato? Questo è stato il primo – masher

risposta

14

Il ciclo for-each non funziona in questo caso. Non è possibile utilizzare un ciclo for-each per inizializzare un array. Il tuo codice:

int[] array = new int[5]; 
for (int i : array) { 
    i = 24; 
} 

si tradurrà in qualcosa di simile al seguente:

int[] array = new int[5]; 
for (int j = 0; j < array.length; j++) { 
    int i = array[j]; 
    i = 24; 
} 

Se questo fosse un array di oggetti, sarebbe ancora sicuro. Fondamentalmente, per-ogni assegna ciascuna voce nella raccolta o matrice, a sua volta, alla variabile che fornisci, che puoi quindi lavorare con. La variabile è non equivalente a un riferimento di matrice. È solo una variabile.

for-each non può essere utilizzato per inizializzare qualsiasi matrice o un insieme, perché loop sui contenuti correnti della matrice o un insieme, dando ogni valore uno alla volta. La variabile in a for-each è non un proxy per un array o un riferimento alla raccolta. Il compilatore non sostituisce il tuo "i" (da "int i") con "array[index]".

Se si dispone di una vasta gamma di data, per esempio, e provare questo, il codice:

Date[] array = new Date[5]; 
for (Date d : array) { 
    d = new Date(); 
} 

sarebbe tradotto in qualcosa di simile a questo:

Date[] array = new Date[5]; 
for (int i = 0; i < array.length; i++) { 
    Date d = array[i]; 
    d = new Date(); 
} 

che come potete vedere sarà non inizializzare la matrice. Finirai con un array che contiene tutti i null.

NOTA: Ho preso il codice sopra, lo ho compilato in un file .class e quindi ho utilizzato jad per decompilarlo. Questo processo mi dà il seguente codice, generato dal compilatore Sun Java (1.6) dal codice di cui sopra:

int array[] = new int[5]; 
int ai[]; 
int k = (ai = array).length; 
for(int j = 0; j < k; j++) 
{ 
    int i = ai[j]; 
    i = 5; 
} 
+0

In realtà, non si traduce in un ciclo while con un iteratore? –

+0

Non sto cercando di dare la traduzione esatta, ma un motivo per cui non funziona. – Eddie

+0

ha senso. Saluti. – masher

3

int è un tipo primitivo nel sistema, in modo che stai in realtà sempre una copia del valore della cella nella matrice, piuttosto che un riferimento a tale cella nella matrice che è possibile assegnare in ....

Lasciami provare e spiegare questo. Se avessi una serie di X, dove X è una classe che ha membri di dati, si otterrebbe un riferimento a una cella diversa in ogni iterazione e sarebbe in grado di cambiare il suo stato chiamando le funzioni su di essa (ad esempio, setValue) .

Quando hai ints è una storia diversa, il tuo int non è un riferimento, è un valore effettivo nello stack poiché è un tipo primitivo, quindi in ogni iterazione, per per copia un valore dall'array in i . Quindi aggiorni il tuo i, ma ciò non ha alcun effetto sull'array.

+0

Tuttavia, questo non è esattamente il motivo dell'errore. Non ha nulla a che fare con int essendo primitivo. Non è possibile utilizzare for-each per inizializzare * qualsiasi * array, indipendentemente dal fatto che il suo contenuto sia primitivo o meno. – Eddie

+0

A meno che la classe non abbia un setValue() esplicito che si desidera chiamare. – Uri

+0

Se si utilizza una matrice di oggetti, questo codice non inizializzerà la matrice. Non ha nulla a che fare con la variabile qui essendo primitiva. – Eddie

5

i è solo una copia dell'int in quel punto dell'array, non un riferimento ad esso. Il ciclo for-each non funziona in questo caso.

0

fare questo, invece:

int[] array = new int[5]; 

// initialise array -> Will work now 
for(int i = 0 ; i< array.length ; i++) 
    array[i] = 24 ; 
+0

Non volevo scrivere tutto questo ogni volta. Sembra che non riesca a farla franca .. :( – masher

+0

benvenuti all'aspetto ripetitivo della programmazione della vita del programmatore – euphoria83

4

Usa

java.util.Arrays.fill(array, 24)

se si sta andando ad essere l'inizializzazione allo stesso valore. Oltre a questo, Eddie è praticamente in discussione nella sua traduzione del costrutto for-each.

+0

bello! D'ora in poi userò molto quella classe! – masher

Problemi correlati