El bucle for en Java, junto con su primo el for-each, son estructuras lógicas que te permiten realizar una y otra vez una acción, siempre y cuando se cumpla una condición booleana.
More...
En el artículo de hoy vamos a ver cómo se utilizan ambas estructuras, y veamos qué trampas nos podemos encontrar en el examen de certificación OCAJ8P.
Bucles for y for-each en Java: qué son y cómo se comen
Los bucles for y for-each en Java son dos maneras de realizar bucles. Aunque su nombre es similar, su estructura es diferente. Con el bucle for tienes más control en la ejecución del bucle.
Estructura del bucle for en Java
El bucle for en Java toma como punto de partida un índice de control. Al final de cada bucle, este índice se actualiza según una regla que estableces en la estructura del bucle. Acto seguido, el bucle comprueba si el índice satisface la condición booleana.
El bucle for comienza con la palabra clave for y un paréntesis, que contiene tres partes.
Índice de control
El índice de control, si fuera un avión de combate
El índice de control, que tradicionalmente te lo encontrarás representado con la variable i de tipo int, puede en realidad tomar cualquier valor; no hace falta ni siquiera que tenga un valor numérico (aunque habitualmente sea un int):
En cualquier caso, no es necesario que declares la variable (o referencia) que utilices como valor de control dentro del paréntesis; puedes utilizar una variable o referencia que exista con anterioridad:
No obstante, si declaras el índice de control en el paréntesis, solo podrás utilizar esta variable o referencia dentro del bucle for.
Condición booleana
La condición booleana, si fuera un señor con lupa
La condición booleana simplemente evalúa si el índice de control tiene, o no, un valor determinado. Si quieres saber más sobre la condición booleana, no dudes en echarle un ojo al artículo que escribí al respecto.
El bucle se continúa ejecutando siempre y cuando el resultado de la evalución sea true.
Actualización del índice de control
Actualización del índice, si fuera un camello dentudo
La tercera parte de la estructura del bucle for en Java consiste en una regla según la cual el índice de control se va a actualizar después de cada iteración. Por ejemplo, se puede sumar una unidad o, como en el muy complicado primer ejemplo que te he puesto, actualizar la String utilizada como control, agregándole un char (es un caso extremo, que no creo que te encuentres nunca. Por lo menos, fuera del examen).
Un bucle for en Java puede tener un número ilimitado de índices de control
Un bucle for puede contener tantos índices de control como sea necesario, pero todos han de ser del mismo tipo. En este caso, la evaluación booleana puede ser más larga, de manera que se evalúen de manera simultánea todos los índices. En la tercera parte de la estructura del bucle, se puede hacer una lista de todas las reglas de actualización de los índices de control:
Qué has de tener en cuenta a la hora de examinar un bucle for en Java
La flexibilidad a la hora de construir un bucle for en Java es tan grande, que puedes prescindir de algunas de las partes de las que te acabo de hablar. Por ejemplo, también puedes establecer una evaluación booleana que siempre sea true. Como consecuencia, el bucle no deja nunca de ejecutarse hasta que el programa se detiene con un error por falta de memoria.
Todo está permitido, con tres condiciones:
Ejemplos de bucles for válidos
En el siguiente ejemplo te muestro varios ejemplos de bucles en los que falta alguno de los elementos (o todos ellos). Recuerda que, para ejecutar los bucles de este ejemplo, necesitas hacerlo por separado El primer bucle for es un bucle infinito, y no va a permitir la ejecución del resto.
Fíjate que en bucle nº 5: aunque el código contenido en el bucle no se llega a ejecutar, el código compila. Esto se debe a que el compilador no sabe cuál es el valor de la variable. Mejor dicho, sabe que la variable se ha iniciado con un valor, pero no "recuerda" qué valor es este. La única manera de hacer que el compilador tenga en cuenta el valor de la variable es utilizando la palabra clave final. Pero entonces surge otro problema:
Dado que cualquier variable marcada como final es invariable, el código no compila, ya que l++ no es legal. Si el índice de control fuera una referencia a un objeto, en lugar de una variable primitiva, final no permite que la referencia se asigne a un nuevo objeto, pero sí permite que el objeto se modifique:
¿Qué ocurre si utilizas directamente los valores true o false en la evaluación?
A diferencia de lo que ocurría si utilizabas false en un if, que era perfectamente válido, no puedes utilizar false en un bucle for en Java, aunque el bucle esté vacío:
El uso de true crea un bucle infinito, ya que la evaluación nunca llega a tener el valor false.
Por último, un bucle for en Java puede prescindir de las llaves, si el código que contiene consta de una sola línea (hasta el primer punto y coma). Vigila la posición del bucle for en ese caso:
El compilador no tiene en cuenta los espacios en blanco, así que lo que ve es: for(;;)}. Después de cerrarse el paréntesis no puede cerrarse una llave.
Orden de ejecución de cada una de las partes de la estructura
Esta parte la has de tener muy clara. Imagínate, por ejemplo, que instancias el índice de control fuera del bucle. Así, tienes acceso a él una vez finalizado este. ¿Sabes qué valor ha adquirido el índice, y por qué?
Este es el orden de ejecución de cada una de las partes de la estructura:
¿Qué crees que imprimirá el siguiente código? El resultado lo tienes más abajo.
El código no se ejecuta, ya que la variable i se ha declarado en el bucle y no se puede acceder a ella desde fuera de este.
Bucles for anidados
Los bucles for anidados consisten en crear un bucle for dentro de otro bucle. Son útiles si quieres, por ejemplo, imprimir el contenido de un array de dos dimensiones:
Más abajo te hablo del bucle for-each, más cómodo para iterar por una lista.
Cómo hackear un bucle: continue/break
Las palabras clave continue y break sirven para hackear la ejecución de cualquier bucle en Java.
Continue, o pasa a la siguiente iteración
La palabra clave continue detiene la ejecución del código en el bucle, y fuerza a que este pase a su siguiente iteración.
Como ves, cuando el valor de i es 3 se cumple la condición del bloque if. Se ejecuta la orden continue y el bucle pasa a su siguiente iteración, es decir, siendo cuatro el valor de i.
Ten en cuenta que el bucle sigue funcionando con normalidad. Si el siguiente valor de i diera como resultado false en la evaluación booleana, la ejecución del código saldría del bucle.
El código tras continue no se ejecuta, asi que este o es la última condición dentro de un if, o el código no compila. Un continue al final del bucle no cambia nada.
Break, o "rompe" el bucle
La palabra clave break detiene de inmediato la ejecución del bucle. Al igual que continue, ha de ser la última condición dentro de un if. Puede aparecer por sí sola al final del bucle, pero en ese caso el bucle se ejecutará solo una vez:
Bucles for anidados con break, continue y etiquetas
Aquí juntamos los bucles anidados que te he enseñado antes, con las palabras clave break y continue. Suponte, por ejemplo, que quieres que el hilo de ejecución abandone todo el complejo de bucles, si el índice de control de un bucle for anidado toma un valor determinado.
En ese caso, puedes utilizar una etiqueta. Las etiquetas son similares a puntos de anclaje, a los que puedes hacer referencia para que, al ejecutarse un break, el hilo de ejecución continúe a partir de dicho punto de anclaje. Quedará más claro con un ejemplo:
Como ves, cuando se ejecuta el break con la etiqueta el hilo de ejecución NO vuelve a entrar en el bucle aunque la etiqueta se encuentre justo antes de este.
En el siguiente ejemplo utilizo el mismo código, pero con continue en lugar de break:
¿Eres capaz de seguir la ejecución, según el resultado obtenido?
Estructura de las etiquetas
Para que una etiqueta sea válida, ha de seguir una serie de reglas.
El bucle for-each en Java
El bucle for-each en Java se utiliza para iterar a lo largo de una lista de objetos o variables primitivas. Es decir que, para el examen de certificación OCAJ8P, se utilizará para objetos de tipo List, ArrayList y para array[], tanto de objetos como de variables primitivas.
En este tipo de bucle no tienes tanto control como en el bucle for que acabamos de ver.
Estructura del bucle for-each
La estructura de este bloque es muy básica. Se compone, de nuevo, de la palabra clave for seguida de un paréntesis. Este contiene tres partes, pero que son más sencillas que las del bucle for anterior.
No se puede prescindir de ninguna de las tres partes.
Aquí tienes un ejemplo más gráfico de la estructura del for each:
Como puedes ver, el único símbolo que aparece dentro del paréntesis son los dos puntos (:) que separan el nombre de la variable local del nombre de la lista que vamos a iterar.
Bucles for-each anidados
Recuerda que, si el array tiene más de una dimensión, la variable local será también un array, pero con una dimensión menos. A continuación te muestro una serie de bucles for-each anidados, partiendo de un array de tres dimensiones. Como ves, conforme vamos avanzando, el array iterado tiene un dimensión menos que su padre. ¿Adivinas por qué?
Con el bucle for en Java tienes la posibilidad de controlar el bucle de muchas maneras. Puedes, por ejemplo, controlar cuántas veces puede ejecutarse. O incluso hacer que, si itera una lista, se salte un elemento. Esto se consigue, por ejemplo, modificando el índice de control de manera que con cada bucle se sumen dos unidades, en lugar de una (i += 2). El bucle for-each está creado de manera específica para iterar listas. Viene a ser un bucle for resumido, con una función específica.
Debido a esta limitación, no te rompas la cabeza si necesitas un control más fino del bucle: utiliza un for clásico, y ya está.
Break y continue en un for-each
El uso de break y continue, tanto por sí solos como con etiquetas, es exactamente igual al uso que hemos visto más arriba en un bucle for normal:
Ejercicios recomendados
Construye bucles for y for-each anidados muy complejos, que te fuercen a seguirlos línea a línea con papel y lapiz. Puedes ejercitar los siguientes puntos:
¿Qué problemas te han surgido? ¿has aprendido u observado algún detalle que me haya dejado yo en el tintero? ¡Espero tus comentarios!
Los recursos con los que yo superé el OCA con una puntuación del 92%
Si estás en serio con la programación en Java, te recomiendo dos recursos esenciales: el manual de Java que te muestro a la izquierda, y los exámenes de práctica de Enthuware. Son los que yo utilicé para obtener un 92% de puntuación.
También existen cursos en español en Udemy, y en inglés en Skillshare, Lynda y Udacity (en este último, gratuitos). Échale un vistazo al apartado Recursos para Java.