8

How does a for-each loop works when it calls a method, either recursively or a different method?

Example:

for(String permutation : permute(remaining))
    {   

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

By the way the method permute takes in a String and returns a set.

Thank you.

user1965283
  • 147
  • 1
  • 3
  • 10

5 Answers5

9

According to the Java Language Specification for the enhanced for statement, the expression:

for ( FormalParameter : Expression ) Statement

Is executed as follows:

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

Thus, the Expression (which must be of type Iterable) only has its iterator() method called once.

ulmangt
  • 5,343
  • 3
  • 23
  • 36
3

Calls it once, stores the result, does foreach.

Like this:

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

Edit: If this is recursive, it really makes no difference. Every layer of recursion simply has its own scope, and thus its own "temp" variable. Thus the permute function will recurse to the lowest level, then each higher level will do its completely separate foreach loop successively.

Jeff
  • 12,555
  • 5
  • 33
  • 60
  • @user1965283 No problem, but don't forget to accept your preferred answer (Which should be ulmangt's, as his answer is cooler than mine) – Jeff Jan 10 '13 at 02:40
2

If we compile this Test

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

and decompile Test.class with JAD we will see that javac replaced for-each with this code

    Set set = new HashSet();
    String s;
    for(Iterator iterator = set.iterator(); iterator.hasNext();)
        s = (String)iterator.next();
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1

Foreach loop works on any class that implements the Iterable interface, and is only syntax sugar for calling hasNext() and next() on an Iterator. Same thread same loop and the function is called once.

1

In your example, the result of permute(remaining) is evaluated before one enters into the loop. While the enhanced for loop is really nothing more than syntactic sugar for iterators, it still follows the same principles as other loops would - it has to have a set to operate with before it can do anything else.

A simpler example would be something like this:

while(input.hasNext())

That's something you may see in projects that read in an indefinite amount of lines. The expression input.hasNext() has to be evaluated first, then you may loop.

Makoto
  • 104,088
  • 27
  • 192
  • 230