java - example - jsp for each list
Eficacia de Java Foreach (6)
Creo que es un compilador optimizado para ejecutarse solo una vez por entrada de bucle.
Tengo algo como esto:
Map<String, String> myMap = ...;
for(String key : myMap.keySet()) {
System.out.println(key);
System.out.println(myMap.get(key));
}
Entonces, ¿se myMap.keySet() una vez en el ciclo foreach ? Creo que sí, pero quiero tu opinión.
Me gustaría saber si el uso de foreach de esta manera ( myMap.keySet() ) tiene un impacto en el rendimiento o es equivalente a esto:
Set<String> keySet = myMap.keySet();
for (String key : keySet) {
...
}
La respuesta está en la Especificación del lenguaje Java, no es necesario descompilar :) Esto es lo que podemos leer sobre la declaración mejorada para :
La declaración mejorada para tiene la forma:
EnhancedForStatement: for ( VariableModifiersopt Type Identifier: Expression) StatementLa expresión debe tener un tipo
Iterableo bien debe ser de un tipo de matriz (§10.1), o se produce un error en tiempo de compilación.El alcance de una variable local declarada en la parte FormalParameter de una instrucción
forforzada (§14.14) es la declaración contenidaEl significado de la declaración mejorada está dada por la traducción en una declaración básica
for.Si el tipo de
Expressiones un subtipo deIterable, entonces permítame ser el tipo de la expresión Expresión.iterator(). El enunciado mejoradofores equivalente a una declaración básicaforel formulario:
for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }Donde
#ies un identificador generado por el compilador que es distinto de cualquier otro identificador (generado por el compilador o de otro modo) que esté dentro del alcance (§6.3) en el punto donde ocurre la declaración for forzada.De lo contrario, la Expresión necesariamente tiene un tipo de matriz,
T[]. Deje queL1 ... Lmsea la secuencia (posiblemente vacía) de las etiquetas que preceden inmediatamente a la declaraciónformejorada. Entonces, el significado de la declaración for mejorada viene dada por la siguiente declaración básicafor:
T[] a = Expression; L1: L2: ... Lm: for (int i = 0; i < a.length; i++) { VariableModifiersopt Type Identifier = a[i]; Statement }Donde a y yo somos identificadores generados por el compilador que son distintos de cualquier otro identificador (generado por el compilador o de otra manera) que están en el alcance en el punto donde ocurre la declaración for forzada.
En su caso, myMap.keySet() devuelve un subtipo de Iterable por lo que su declaración mejorada es equivalente a la siguiente declaración básica for :
for (Iterator<String> iterator = myMap.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
System.out.println(key);
System.out.println(myMap.get(key));
}
Y myMap.keySet() se llama así solo una vez.
Sí, se llama solo de una u otra forma
Si quiere estar absolutamente seguro, compilarlo en ambos sentidos y descompilarlo y comparar. Hice esto con la siguiente fuente:
public void test() {
Map<String, String> myMap = new HashMap<String, String>();
for (String key : myMap.keySet()) {
System.out.println(key);
System.out.println(myMap.get(key));
}
Set<String> keySet = myMap.keySet();
for (String key : keySet) {
System.out.println(key);
System.out.println(myMap.get(key));
}
}
y cuando descompilé el archivo de clase con Jad , obtengo:
public void test()
{
Map myMap = new HashMap();
String key;
for(Iterator iterator = myMap.keySet().iterator(); iterator.hasNext(); System.out.println((String)myMap.get(key)))
{
key = (String)iterator.next();
System.out.println(key);
}
Set keySet = myMap.keySet();
String key;
for(Iterator iterator1 = keySet.iterator(); iterator1.hasNext(); System.out.println((String)myMap.get(key)))
{
key = (String)iterator1.next();
System.out.println(key);
}
}
Así que ahí está tu respuesta. Se llama una vez con forma for-loop.
Solo se llama una vez. De hecho, usa un iterador para hacer el truco.
Además, en tu caso, creo que deberías usar
for (Map.Entry<String, String> entry : myMap.entrySet())
{
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
para evitar buscar en el mapa cada vez.
keySet() se llama solo una vez. El "bucle Iterable mejorado" se basa en la interfaz Iterable , que utiliza para obtener un Iterator , que luego se utiliza para el bucle. Ni siquiera es posible iterar sobre un Set de ninguna otra manera, ya que no hay ningún índice ni nada por el cual pueda obtener elementos individuales.
Sin embargo, lo que realmente debería hacer es abandonar por completo este tipo de problemas de micro-optimización: si alguna vez tiene problemas reales de rendimiento, existe la probabilidad de que sea algo que nunca había pensado por sí solo.