Will this code be evaluated at each iteration?

I have for each loop:

for (Component c : container.getComponents()) { // Loop code } 

getComponents on every iteration? Does it make sense to call getComponents in front of the appearance and work only with the cached array?

+4
source share
5 answers

No, getComponents () will be called only once.

This is the equivalent:

 for (Iterator<Component> iterator = container.getComponents().getIterator(); iterator.hasNext(); ) { Component c = iterator.next(); ... } 

From section 14.14.2 Java Language Specifications :

The enhanced for statement has the following form:

EnhancedForStatement:

 for ( VariableModifiersopt Type Identifier: Expression) Statement 

An expression must either be of type Iterable, or it must be of an array type (ยง10.1),> or a compile-time error. The scope of the local variable declared in the extended FormalParameter part for (ยง14.14) is a contained statement

The value of the extended for statement is given by translating into a base for statement.

If the type of the expression is a subtype of Iterable , then let me be the type of the expression Expression.iterator() . The extension for the statement is equivalent to the main for expression of the form:

 for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement } 
+17
source

getComponents will be called once and will return an Iterator. Then this iterator will be called using the next () and hasNext () methods.

Refresh Here is a little more detail to try and release Skeet Jon Skeet on this answer.

The following program shows how to call iterator once, even if there are three elements in the collection.

 public static void main(String[] args) { List<String> list = new ArrayList<String>() { public java.util.Iterator<String> iterator() { System.out.println("iterator() called"); return super.iterator(); }; }; list.add("a"); list.add("b"); list.add("c"); for (String s : list) { System.out.println(s); } } 

Output:

 iterator() called a b c 

If you run this through a Java decompiler, you will find the following code:

  String s; for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(s)) s = (String)iterator.next(); 

Add, since we know from JLS 14.14.1 that the first section of the for statement is executed only once, we can rest assured that the iterator method will not be called several times.

+10
source

Java LanguageSpecification 14.14.2 says:

EnhancedForStatement:
for ( VariableModifiersopt Type Identifier: Expression) Statement

If the type of the expression is a subtype of Iterable, then let me be the type of the expression Expression.iterator (). The extension for the statement is equivalent to the base for the statement of the form:

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

Where #i is the identifier generated by the compiler, different from any other identifiers (generated by the compiler or otherwise) that are in scope (section 6.3) at the time when.

Thus, an expression is evaluated only once (during initialization).

+3
source

Is getComponents for each iteration?

No. Java foreach loop is based on Iterable interface and is equivalent to this code.

 Iterator<Component> i = container.getComponents().iterator while(i.hasNext()) { Component c = i.next(); // loop body goes here } 

The only difference is that the Iterator is hidden.

+2
source

I would think that when compiling it would be translated as a "long arm" cycle, as when using for (int i = 0 ....

Isn't the foreach loop just a software temporary saver with actual bytecode conversion just like a long arm does ??

In short, getComponent () should only be called once

0
source

All Articles