2013-01-10 20 views
9

Jak działa pętla for-each, gdy wywołuje metodę rekursywnie lub inną metodą?Jak działa pętla for-each?

przykład:

for(String permutation : permute(remaining)) 
    { 

     // Concatenate the first character with the permutations of the remaining chars 
     set.add(chars.charAt(i) + permutation); 
    } 

drogą Sposób przestawiać następuje w łańcuchu i zwraca zestaw.

Dziękuję.

+0

Dlaczego nie można zakodować ją i krok choćby w debugerze, takim jak Eclipse? – OldProgrammer

+0

Nie ma to nic wspólnego z rekursją, jak to zostało postawione. –

+0

lub użyj javap do demontażu! – auselen

Odpowiedz

9

Według Java Language Specification na rachunku enhanced for, wyrażenie:

for (FormalParameter : Expression) Statement 

jest realizowana w następujący sposób:

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

Zatem Expression (który musi być typu Iterable) ma tylko jego iterator() metoda raz wywoływana.

+0

Dziękuję człowieku. :) – user1965283

+0

@ user1965283: Witamy w SO. Proszę przyjąć odpowiedź: http://stackoverflow.com/faq – Jayan

1

Foreach pętla działa na każdej klasy, która implementuje interfejs Iterable i tylko cukier składnia do wywoływania hasNext() i next() na Iterator. Ten sam wątek jest tą samą pętlą, a funkcja jest wywoływana raz.

+0

Dziękuję za odpowiedź. :) – user1965283

3

Wywołuje go raz, przechowuje wynik, robi foreach.

Jak to:

Collection<String> temp = permute(remaining); 
for(String permutation : temp) { 
... 
} 

Edycja: Jeśli jest rekurencyjna, to naprawdę nie ma znaczenia. Każda warstwa rekursji ma po prostu swój własny zakres, a więc własną zmienną "temp". Tak więc funkcja permutacji powróci do najniższego poziomu, następnie każdy wyższy poziom wykona kolejno oddzielną pętlę .

+0

Dziękuję za to. :) – user1965283

+0

@ user1965283 Nie ma problemu, ale nie zapomnij przyjąć preferowanej odpowiedzi (która powinna być ulmangta, ponieważ jego odpowiedź jest chłodniejsza niż moja). – Jeff

1

W twoim przykładzie wynik permute(remaining) jest oceniany przed jeden wchodzi w pętli. O ile ulepszona pętla for jest właściwie niczym innym, jak syntaktycznym cukrem dla iteratorów, to nadal działa na tych samych zasadach, co inne pętle - musi mieć zestaw do działania, zanim będzie mógł zrobić cokolwiek innego.

Prostsza Przykładem może być coś takiego:

while(input.hasNext()) 

To coś można zobaczyć w projektach, które czytają w nieokreślonej ilości linii. Wyrażenie input.hasNext() musi zostać najpierw ocenione, a następnie można wykonać pętlę.

+0

Dziękuję za odpowiedź. :) – user1965283

1

Jeśli skompilować ten test

class Test { 
    public static void main(String[] args) throws Exception { 
     Set<String> set = new HashSet<>(); 
     for (String s : set) { 
     } 
    } 
} 

i dekompilacji Test.class ze JAD widzimy, że javac zastąpiony for-each z tym kodem

Set set = new HashSet(); 
    String s; 
    for(Iterator iterator = set.iterator(); iterator.hasNext();) 
     s = (String)iterator.next();