2012-12-21 4 views
6

Credo di aver notato che per alcuni Iterables (come questo IterableString class) viene creato un nuovo iteratore o l'iteratore si reimposta in qualche modo all'inizio con ogni nuovo costrutto foreach ma quello ciò non sembra verificarsi con altri iterabili ...Java Iterables "Ripristino" Iterator con ogni Foreach Construct

ad esempio, se si esegue il seguente codice:


import java.util.ArrayList; 


public class test { 


    public static void main(String args[]) { 
    IterableString x = new IterableString("ONCE"); 

    System.out.println("***"); 
    for (char ch : x){ 
     System.out.println(ch); 
    } 

    System.out.println("***"); 
    for (char ch : x){ 
     System.out.println(ch); 
    } 

    ArrayList y = new ArrayList(); 
    y.add('T'); 
    y.add('W'); 
    y.add('I'); 
    y.add('C'); 
    y.add('E'); 

    System.out.println("***"); 
    for (char ch : y){ 
     System.out.println(ch); 
    } 

    System.out.println("***"); 
    for (char ch : y){ 
     System.out.println(ch); 
    } 

    System.out.println(); 
    } 
} 

vedrete il seguente output:


*** 
O 
N 
C 
E 
*** 
*** 
T 
W 
I 
C 
E 
*** 
T 
W 
I 
C 
E 

Il secondo ciclo foreach con x sembra iniziare da dove era stato interrotto (dopo l'ultimo elemento), ma il secondo ciclo foreach con y sembra iniziare dal punto in cui è iniziato la prima volta (al primo elemento). Perché questo e come possiamo rendere Iterables che si comportano come quest'ultimo (ArrayLists)?

Più concretamente, con quale precisione modificheremmo una classe come IterableString per funzionare come ArrayList?

+2

cosa diavolo è 'IterableString' ?? quell'oggetto sconosciuto potrebbe avere qualcosa a che fare con il modo in cui l'iteratore è configurato ... – mre

+3

Javadoc per 'Iterable' non sembra dire molto per imporre che ogni chiamata a' iterator() 'restituisca un nuovo' Iterator' - ma quella sembra essere la pratica accettata dal JDK (e ragionevole). Quindi sembra un "bug" di chi abbia mai creato 'IterableString'. –

risposta

4

La classe IterableString (come definita dal vostro linked article) è sia la Iterable che la Iterator. Se o non che sia una buona idea è discutibile - ma una semplice correzione è:

// This method implements Iterable. 
    public Iterator<Character> iterator() { 
    return new IterableString(this.str); 
    } 
+0

Grazie! Sono stato buttato fuori da problemi simili che ho visto con altri iterabili (come [questo] (http://code.hammerpig.com/how-to-read-really-large-files-in-java.html) dove la classe iteratore nidificata aveva un altro problema con la necessità di rendere conto del fatto che era consapevole dello stato di cambiare i componenti nel suo sottoclasse). Per qualche ragione l'apparente coerenza dell'errore mi ha dato l'impressione che ci fosse qualcosa di speciale in corso con iterables come ArrayList in contrapposizione a pezzi rotti negli iterables non standard che stavo guardando. – user1920345

-1

Un ArrayList è in grado di essere iterato in un ciclo foreach java perché implementa l'interfaccia Iterable in Java. L'interfaccia Iterable delinea un metodo iterator che restituisce un iteratore per la raccolta. L'uso di un ciclo foreach in java utilizza l'iteratore da questo metodo sotto il cofano. Ogni volta che crei un nuovo ciclo foreach, lo ArrayList fornisce un nuovo iteratore.

Se si desidera creare una classe che può essere iterata su un ciclo foreach in Java, è necessario implementare l'interfaccia Iterable e definire come iterare sulla raccolta.

+1

Questo ancora non risponde alla domanda degli OP –

+0

Sono un po 'confuso dal tuo commento @ Code-Guru. Forse sto fraintendendo la domanda, ma ho delineato il motivo per cui un ArrayList ha quel comportamento in un ciclo foreach e come imitare quello in una classe definita dall'utente. – user1897691

+0

La domanda è perché la classe 'IterableString' si comporta diversamente da' ArrayList'. –

Problemi correlati