Se stai semplicemente vagando sulla raccolta per leggere tutti i valori, allora non c'è alcuna differenza tra l'utilizzo di un iteratore o la nuova sintassi del ciclo, poiché la nuova sintassi utilizza solo l'iteratore sott'acqua.
Se tuttavia, intendi per loop il vecchio loop "c-style":
for(int i=0; i<list.size(); i++) {
Object o = list.get(i);
}
Quindi il nuovo for loop, o iteratore, può essere molto più efficiente, a seconda della struttura dei dati sottostante. La ragione di ciò è che per alcune strutture di dati get(i)
è un'operazione O (n), che rende il ciclo un'operazione O (n 2 ). Un elenco tradizionale collegato è un esempio di tale struttura di dati. Tutti gli iteratori hanno come requisito fondamentale che next()
dovrebbe essere un'operazione O (1), rendendo il ciclo O (n).
Per verificare che l'iteratore sia utilizzato sott'acqua dalla nuova sintassi del ciclo, confrontare i codici byte generati dai seguenti due frammenti Java. Prima il ciclo for:
List<Integer> a = new ArrayList<Integer>();
for (Integer integer : a)
{
integer.toString();
}
// Byte code
ALOAD 1
INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
ASTORE 3
GOTO L2
L3
ALOAD 3
INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 2
ALOAD 2
INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
POP
L2
ALOAD 3
INVOKEINTERFACE java/util/Iterator.hasNext()Z
IFNE L3
E in secondo luogo, l'iteratore:
List<Integer> a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();)
{
Integer integer = (Integer) iterator.next();
integer.toString();
}
// Bytecode:
ALOAD 1
INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
ASTORE 2
GOTO L7
L8
ALOAD 2
INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 3
ALOAD 3
INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
POP
L7
ALOAD 2
INVOKEINTERFACE java/util/Iterator.hasNext()Z
IFNE L8
Come puoi vedere, il codice byte generato è effettivamente identico, quindi non vi è alcuna penalità prestazionale nell'uso di entrambi i moduli. Pertanto, dovresti scegliere la forma di loop che è più esteticamente attraente per te, per la maggior parte delle persone che sarà il ciclo for-each, in quanto ha meno codice boilerplate.