2012-12-21 23 views
6

Wierzę, że zauważyłem, że dla niektórych Iterables (takich jak ten IterableString class) albo tworzony jest nowy iterator, albo iterator jakoś resetuje się na początek z każdą nową konstrukcją foreach, ale to to nie wydaje się występować z innymi Iterables ...Iterables "Resetting" Iterator z każdą strukturą foreach

na przykład, jeśli uruchomić następujący kod:


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(); 
    } 
} 

pojawi się następujący komunikat:


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

Druga pętla foreach z x wydaje się zaczynać od miejsca, w którym została przerwana (po ostatnim elemencie), ale druga pętla foreach z y wydaje się zaczynać od miejsca, w którym rozpoczęła się po raz pierwszy (przy pierwszym elemencie). Dlaczego tak jest i jak możemy stworzyć Iterables, które zachowują się tak samo jak te drugie (ArrayLists)?

Bardziej konkretnie, jak dokładnie zmodyfikowalibyśmy klasę, taką jak IterableString, aby działała jak ArrayList?

+2

co to jest "IterableString" ?? ten nieznany obiekt może mieć coś wspólnego ze sposobem konfigurowania iteratora ... – mre

+3

Javadoc dla 'Iterable' nie wydaje się powiedzieć dużo, aby narzucić każdemu wywołaniu' iterator() 'zwraca nowy' Iterator' - ale wydaje się, że jest to akceptowana praktyka JDK (i rozsądna). Wygląda więc jak "błąd", który kiedykolwiek stworzył 'IterableString'. –

Odpowiedz

4

Klasa IterableString (według definicji linked article) to Iterable i Iterator. To, czy jest to dobry pomysł, czy nie, jest dyskusyjne - ale prosta naprawa to:

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

Dzięki! Zostałem wyrzucony przez podobne problemy, które widziałem z innymi iterabelami (jak [this one] (http://code.hammerpig.com/how-to-read-really-large-files-in-java.html) gdzie klasa zagnieżdżonych iteratorów miała inny problem z tym, że musiała wyjaśnić fakt, że była świadoma zmiany komponentów w swojej klasie zewnętrznej). Z jakiegoś powodu pozorna konsekwencja błędu dała mi wrażenie, że dzieje się coś specjalnego z iterabilami, takimi jak ArrayList, w przeciwieństwie do zepsutych elementów w niestandardowych iterałach, na które patrzyłem. – user1920345

-1

Może być iterowane w pętli foreach Java, ponieważ implementuje interfejs Iterable w Javie. Interfejs Iterable określa metodę, która zwraca iterator dla kolekcji. Użycie pętli foreach w java używa iteratora z tej metody pod maską. Za każdym razem, gdy tworzysz nową pętlę foreach, ArrayList dostarcza nowy iterator.

Jeśli chcesz utworzyć klasę, która może być iterowana przy użyciu pętli foreach w Javie, musisz zaimplementować interfejs Iterable i zdefiniować sposób iteracji w kolekcji.

+1

To nadal nie odpowiada na pytanie OP –

+0

Jestem trochę zdezorientowany twoim komentarzem @ Code-Guru. Być może nie rozumiem tego pytania, ale wyjaśniłem, dlaczego ArrayList ma to zachowanie w pętli foreach i jak naśladować to w klasie zdefiniowanej przez użytkownika. – user1897691

+0

Pytanie brzmi, dlaczego klasa 'IterableString' zachowuje się inaczej niż' ArrayList'. –