Considerar:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
¿Cómo sería el for
bucle equivalente sin usar el para cada sintaxis?
java
foreach
syntactic-sugar
Jay R.
fuente
fuente
Respuestas:
Tenga en cuenta que si necesita usarlo
i.remove();
en su bucle o acceder al iterador real de alguna manera, no puede usar elfor ( : )
idioma, ya que el iterador real simplemente se infiere.Como señaló Denis Bueno, este código funciona para cualquier objeto que implemente la
Iterable
interfaz .Además, si el lado derecho de la
for (:)
expresión idiomática es un objeto enarray
lugar de unIterable
objeto, el código interno usa un contador de índice int y, en suarray.length
lugar, se compara. Consulte la Especificación del lenguaje Java .fuente
import java.util.Iterator;
yimport java.lang.Iterable;
java.util.Iterator
no se implementa,Iterable
por lo que no puedefor(String s : (Iterator<String>)foo)
. Entiendo por qué es esto, pero es irritante.La construcción para cada uno también es válida para matrices. p.ej
que es esencialmente equivalente a
Entonces, resumen general:
[nsayer] La siguiente es la forma más larga de lo que está sucediendo:
[Denis Bueno]
fuente
El
foreach
bucle , agregado en Java 5 (también llamado "bucle mejorado para"), es equivalente a usar unjava.util.Iterator
azúcar sintáctico --it para la misma cosa. Por lo tanto, al leer cada elemento, uno por uno y en orden,foreach
siempre se debe elegir un en lugar de un iterador, ya que es más conveniente y conciso.para cada
Iterador
Hay situaciones en las que debe usar un
Iterator
directamente. Por ejemplo, intentar eliminar un elemento mientras se usa unaforeach
lata (¿será?) Resultará en aConcurrentModificationException
.foreach
vsfor
.: diferencias básicasLa única diferencia práctica entre
for
yforeach
es que, en el caso de los objetos indexables, no tiene acceso al índice. Un ejemplo cuandofor
se requiere el bucle básico :Aunque podría crear manualmente una variable int de índice separada con
foreach
,no se recomienda, ya que el alcance variable no es ideal, y el
for
bucle básico es simplemente el formato estándar y esperado para este caso de uso.foreach
vsfor
.: rendimientoAl acceder a colecciones, a
foreach
es significativamente más rápido que elfor
acceso a la matriz del bucle básico . Sin embargo, al acceder a matrices, al menos con matrices primitivas y envolventes, el acceso a través de índices es dramáticamente más rápido.Momento de la diferencia entre el iterador y el acceso al índice para matrices int primitivas
Los índices son 23- 40 por ciento más rápido que cuando se accede a los iteradores
int
oInteger
matrices. Aquí está el resultado de la clase de prueba en la parte inferior de esta publicación, que suma los números en una matriz primitiva-int de 100 elementos (A es iterador, B es índice):También ejecuté esto para una
Integer
matriz, y los índices siguen siendo el claro ganador, pero solo entre un 18 y un 25 por ciento más rápido.Para las colecciones, los iteradores son más rápidos que los índices.
Para algunos
List
deIntegers
, sin embargo, los iteradores son el claro ganador. Simplemente cambie la matriz int en la clase de prueba a:Y realice los cambios necesarios en la función de prueba (
int[]
toList<Integer>
,length
tosize()
, etc.):En una prueba son casi equivalentes, pero con las colecciones, el iterador gana.
* Esta publicación se basa en dos respuestas que escribí en Stack Overflow:
Usos y sintaxis para cada ciclo en Java
¿Debo usar un iterador o un forloop para iterar?
Más información: ¿Cuál es más eficiente, un ciclo para cada uno o un iterador?
La clase de prueba completa
Creé esta clase de comparar el tiempo que se tarda en hacer dos cosas después de leer esta pregunta en Stack Overflow:
fuente
for(int value : int_array) {/* loop content */}
es el más lento en su prueba porque es sintácticamente equivalente afor(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}
, que no es lo que compara su prueba.int value = int_array[i];
al comienzo de su prueba) bucle, entonces también podrían usar foreach. A menos que también necesiten acceso al índice, por alguna razón. En resumen, todo depende del contexto.)Aquí hay una respuesta que no asume el conocimiento de los iteradores de Java. Es menos preciso, pero es útil para la educación.
Mientras programamos, a menudo escribimos código similar al siguiente:
La sintaxis foreach permite que este patrón común se escriba de una manera más natural y menos sintácticamente ruidosa.
Además, esta sintaxis es válida para objetos como Listas o Conjuntos que no admiten la indexación de matrices, pero que implementan la interfaz Iterable de Java.
fuente
El ciclo for-each en Java usa el mecanismo de iterador subyacente. Entonces es idéntico a lo siguiente:
fuente
En las características de Java 8 puede usar esto:
Salida
fuente
Está implícito en la respuesta de nsayer, pero vale la pena señalar que los OP para la sintaxis (..) funcionarán cuando "someList" sea algo que implemente java.lang.Iterable: no tiene que ser una lista o una colección de java.util. Incluso sus propios tipos, por lo tanto, se pueden usar con esta sintaxis.
fuente
Como se define en JLS , cada ciclo puede tener dos formas:
Si el tipo de expresión es un subtipo de,
Iterable
entonces la traducción es como:Si la expresión necesariamente tiene un tipo de matriz,
T[]
entonces:Java 8 ha introducido transmisiones que generalmente funcionan mejor. Podemos usarlos como:
fuente
Una sintaxis de bucle foreach es:
Ejemplo:
Salida:
ADVERTENCIA: puede acceder a los elementos de la matriz con el bucle foreach, pero NO puede inicializarlos. Use el
for
bucle original para eso.ADVERTENCIA: debe hacer coincidir el tipo de matriz con el otro objeto.
Si desea editar elementos, use el
for
bucle original de esta manera:Ahora si volcamos s a la consola, obtenemos:
fuente
La construcción de bucle "para cada" de Java permitirá la iteración sobre dos tipos de objetos:
T[]
(matrices de cualquier tipo)java.lang.Iterable<T>
La
Iterable<T>
interfaz tiene un solo método:Iterator<T> iterator()
. Esto funciona en objetos de tipoCollection<T>
porque laCollection<T>
interfaz se extiendeIterable<T>
.fuente
El concepto de un bucle foreach como se menciona en Wikipedia se destaca a continuación:
Entonces, el concepto de un bucle foreach describe que el bucle no usa ningún contador explícito, lo que significa que no hay necesidad de usar índices para recorrer la lista, por lo que salva al usuario del error de uno por uno. Para describir el concepto general de este error off-by-one, tomemos un ejemplo de un ciclo para recorrer en una lista usando índices.
Pero suponga que si la lista comienza con el índice 1, este bucle generará una excepción, ya que no encontrará ningún elemento en el índice 0 y este error se llama error de uno por uno. Entonces, para evitar este error off-by-one, se utiliza el concepto de un bucle foreach. También puede haber otras ventajas, pero creo que este es el concepto principal y la ventaja de usar un bucle foreach.
fuente
En Java 8, presentaron para cada uno. Usando la lista, los mapas se pueden enlazar.
Repetir una lista usando para cada
o
Recorrer un mapa usando para cada
o
fuente
fuente
El uso de versiones anteriores de Java, incluido el
Java 7
uso deforeach
bucle, de la siguiente manera.La siguiente es la última forma de usar el
foreach
bucle enJava 8
(repita una lista con la
forEach
expresión + lambda o referencia de método)Para más información consulte este enlace.
https://www.mkyong.com/java8/java-8-foreach-examples/
fuente
Aquí hay una expresión equivalente.
fuente
También tenga en cuenta que el uso del método "foreach" en la pregunta original tiene algunas limitaciones, como no poder eliminar elementos de la lista durante la iteración.
El nuevo bucle for es más fácil de leer y elimina la necesidad de un iterador separado, pero solo es realmente utilizable en pases de iteración de solo lectura.
fuente
removeIf
podría ser la herramienta adecuadaUna alternativa a forEach para evitar su "para cada uno":
Variante 1 (simple):
Variante 2 (ejecución paralela (más rápida)):
fuente
for(
formulario si me gusta asegurarme de que se usa el mismo hilo. Me gusta usar la forma de flujo si me gusta permitir la ejecución multiproceso.Agrega belleza a su código al eliminar todo el desorden de bucle básico. Le da un aspecto limpio a su código, justificado a continuación.
for
Bucle normal :Usando para cada uno:
for-each es una construcción sobre una colección que implementa Iterator . Recuerde que su colección debe implementar Iterator ; de lo contrario no puede usarlo para cada uno.
La siguiente línea se lee como " para cada TimerTask t en la lista " .
Hay menos posibilidades de errores en el caso de for-each. No tiene que preocuparse por inicializar el iterador o inicializar el contador de bucle y terminarlo (donde hay margen para errores).
fuente
Antes de Java 8, debe usar lo siguiente:
Sin embargo, con la introducción de Streams en Java 8 puede hacer lo mismo con mucha menos sintaxis. Por ejemplo, para tu
someList
puedes hacer:Puede encontrar más información sobre las transmisiones aquí .
fuente
The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
Se vería algo así. Muy asqueroso.
Hay una buena valoración crítica en cada en la documentación de Sun .
fuente
Como tantas buenas respuestas dicen, un objeto debe implementar el
Iterable interface
si quiere usar unfor-each
bucle.Publicaré un ejemplo simple e intentaré explicar de una manera diferente cómo un
for-each
bucle.El
for-each
ejemplo del bucle:Luego, si usamos
javap
para descompilar esta clase, obtendremos esta muestra de código de bytes:Como podemos ver en la última línea de la muestra, el compilador convertirá automáticamente el uso de la
for-each
palabra clave al uso de unIterator
en tiempo de compilación. Eso puede explicar por qué el objeto, que no implementa elIterable interface
, arrojará unException
cuando intente usar elfor-each
bucle.fuente
El Java para cada bucle (también conocido como bucle mejorado) es una versión simplificada de un bucle for. La ventaja es que hay menos código para escribir y menos variables para administrar. La desventaja es que no tiene control sobre el valor del paso y no tiene acceso al índice del bucle dentro del cuerpo del bucle.
Se utilizan mejor cuando el valor del paso es un simple incremento de 1 y cuando solo necesita acceso al elemento de bucle actual. Por ejemplo, si necesita recorrer todos los elementos de una matriz o colección sin mirar por delante o por detrás del elemento actual.
No hay inicialización de bucle, no hay condición booleana y el valor del paso es implícito y es un incremento simple. Es por eso que se consideran mucho más simples que los regulares para los bucles.
Los bucles mejorados siguen este orden de ejecución:
1) cuerpo de bucle
2) repita desde el paso 1 hasta que se haya recorrido toda la matriz o colección
Ejemplo: matriz de enteros
La variable currentValue contiene el valor actual que se está repitiendo en la matriz intArray. Observe que no hay un valor de paso explícito: siempre es un incremento de 1.
Se puede pensar que el colon significa "en". Por lo tanto, los estados de declaración de bucle for mejorados: repiten sobre intArray y almacenen el valor int de la matriz actual en la variable currentValue.
Salida:
Ejemplo: matriz de cadenas
Podemos usar el ciclo for-each para iterar sobre una matriz de cadenas. La declaración de bucle indica: repita sobre la matriz de cadenas myStrings y almacene el valor de cadena actual en la variable currentString.
Salida:
Ejemplo: lista
El bucle for mejorado también se puede usar para iterar sobre java.util.List de la siguiente manera:
La declaración de bucle dice: repita sobre myList List of Strings y almacene el valor de List actual en la variable currentItem.
Salida:
Ejemplo: conjunto
El bucle for mejorado también se puede usar para iterar sobre un java.util.Set de la siguiente manera:
La declaración de bucle dice: bucle sobre mySet Set of Strings y almacene el valor Set actual en la variable currentItem. Tenga en cuenta que como se trata de un conjunto, los valores de cadena duplicados no se almacenan.
Salida:
Fuente: Loops en Java - Guía definitiva
fuente
fuente
El lenguaje para cada Java solo se puede aplicar a matrices u objetos de tipo * Iterable . Este modismo está implícito, ya que realmente está respaldado por un iterador. El programador programa el iterador y, a menudo, utiliza un índice entero o un nodo (según la estructura de datos) para realizar un seguimiento de su posición. En el papel, es más lento que un ciclo for regular, al menos para estructuras "lineales" como matrices y listas, pero proporciona una mayor abstracción.
fuente
Esto se ve loco pero bueno, funciona
Esto funciona. magia
fuente
Como muchas de las otras respuestas dicen correctamente, el
for
each
loop
azúcar sintáctico es solo sobre el mismo viejofor
loop
y el compilador lo traduce al mismo bucle for antiguo.javac (open jdk) tiene un interruptor
-XD-printflat
, que genera un archivo java con todo el azúcar sintáctico eliminado. el comando completo se ve asíEntonces, eliminemos el azúcar sintáctico
Para responder a esta pregunta, creé un archivo y escribí dos versiones de
for
each
, una conarray
y otra con unlist
. mijava
archivo se veía así.Cuando
compiled
este archivo con el interruptor anterior, obtuve el siguiente resultado.Puede ver que junto con el otro azúcar sintáctico (Autoboxing) para cada bucle se cambió a bucles simples.
fuente
Itera sobre todos los objetos en la tabla Artículos.
fuente