2016-01-26 31 views
25

Il ciclo foreach di Java inizia dal primo oggetto e in modo lineare funziona fino alla fine? Ad esempioIl ciclo foreach di Java conserva l'ordine?

String[] names = new String[] {"Zoe", "Bob", "Charlie", "Alex"}; 
for(String name : names) { 
    //do stuff... 
} 

La stringa "Zoe" viene sempre elaborata per prima, seguita da "Bob" ecc.? Non avviene ordinamento? L'ho provato da solo e non ne ho trovato, ma ho bisogno di una garanzia e non ho trovato nulla nei documenti.

+4

risposta breve: sì, per gli array lo fa. (un po ') risposta più lunga: dipende dall'oggetto che si itera sopra – ParkerHalo

+0

@ParkerHalo che ne dici di 'String's? – Celeritas

+1

Domanda: perché l'ordinamento (o qualsiasi altra modifica) deve essere applicato semplicemente usando un ciclo (non importa se si utilizza foreach o un iteratore direttamente)? – Thomas

risposta

25

Sì. L'ordine non è cambiato. Questo si applica a tutti i tipi di collezioni dello Java Collection Framework che implementano lo iterator interface utilizzato dal ciclo for. Se si desidera ordinare la matrice, è possibile utilizzare Arrays.sort(names)

+1

ne sei sicuro? Non è jraas arraylist che implementa l'interfaccia Iterable (non l'interfaccia di Iterator). – ParkerHalo

+0

@ParkerHalo Bene, 'Iterable' definisce' Iterator iterator() 'quindi sono praticamente equivalenti in questo caso. – Kayaman

+2

quindi devo essere in disaccordo !!! "Questo vale per tutti i tipi di collezioni ... implementando l'interfaccia [iterable]". Il 'HashSet ' implementa anche l'interfaccia iterabile e ** NON ** mantiene l'ordine! – ParkerHalo

26

Il ciclo potenziato for è specificato in JLS 14.14.2, dove viene scritto il codice equivalente.

Può essere utilizzato per il loop su matrici e istanze di Iterable.

  • Per un array, l'ordine di iterazione verrà sempre mantenuto ed essere coerente tra le esecuzioni. Questo perché è equivalente a un semplice ciclo for con un indice che va dall'inizio della matrice alla sua fine.

    La maggiore istruzione for è equivalente ad una base per enunciato della forma:

    T[] #a = Expression; 
    L1: L2: ... Lm: 
    for (int #i = 0; #i < #a.length; #i++) { 
        {VariableModifier} TargetType Identifier = #a[#i]; 
        Statement 
    } 
    

    #a e #i sono automaticamente identificatori generati che sono distinti da altri identificatori (generati automaticamente o altro) che sono nel campo di applicazione nel punto in cui si verifica l'enunciato potenziato.

  • Per un Iterable, seguirà l'ordine del corrispondente Iterator (recuperato chiamando Iterable.iterator()), che può o non può essere coerente tra piste.

    La maggiore istruzione for è equivalente ad una base per enunciato della forma:

    for (I #i = Expression.iterator(); #i.hasNext();) { 
    {VariableModifier} TargetType Identifier = 
        (TargetType) #i.next(); 
        Statement 
    } 
    

    #i è un identificatore generato automaticamente che è distinto da altri identificatori (generati automaticamente o altro) che sono scope (§6.3) nel punto in cui si verifica l'enunciato enhanced for.

    È necessario fare riferimento a Javadoc di ciascun tipo per verificare se un ordine è coerente o meno. Ad esempio, it is explicitely specified that for List, the iterator retains the order:

    Restituisce un iteratore sugli elementi in questo elenco in sequenza corretta.

    Mentre it is explicitely specified that for Set, the order is unspecified (unless an extra guarantee is made):

    Gli elementi vengono restituiti in un ordine particolare (a meno che questo insieme è un esempio di una classe che fornisce una garanzia).