Bucles anidados en Java
Combina bucles dentro de bucles en Java para procesar datos multidimensionales, con patrones para matrices y cuadrículas.
Un bucle anidado es un bucle dentro de otro bucle. El bucle interior se ejecuta hasta completarse en cada pasada del bucle exterior, por lo que el cuerpo se ejecuta externo × interno veces. Esta es la estructura básica para cualquier problema que implique filas y columnas, pares o datos multidimensionales.
Este capítulo asume que conoces las formas básicas de bucles — el bucle for y el bucle while. Cualquier bucle puede anidarse dentro de otro; los ejemplos a continuación usan for porque es el más común, pero la regla es la misma para while y para el for-each.
Dos bucles for
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
System.out.println(i + "," + j);
}
}Salida:
1,1
1,2
1,3
2,1
2,2
2,3
3,1
3,2
3,3Para cada valor de i, el bucle interior recorre j de 1 a 3 antes de que i avance. Ten en cuenta que j se reinicializa a 1 en cada pasada exterior — el bucle interior comienza de nuevo cada vez que el bucle exterior se repite. Mantén las variables de bucle distintas (i y j aquí); reutilizar el mismo nombre dentro de ambos bucles es una fuente común de errores.
Recorrer un array 2D
El uso clásico de los bucles anidados es iterar sobre una matriz:
int[][] grid = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
System.out.print(grid[r][c] + " ");
}
System.out.println();
}Cada fila de la cuadrícula es en sí misma un array; el bucle exterior itera las filas, el bucle interior itera las celdas de cada fila. La forma for-each es aún más limpia cuando no necesitas los índices:
for (int[] row : grid) {
for (int cell : row) {
System.out.print(cell + " ");
}
System.out.println();
}Imprimir patrones
Los bucles anidados son un ejercicio clásico para imprimir patrones. Un triángulo de asteriscos:
int rows = 5;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}Salida:
*
**
***
****
*****El conteo del bucle interior depende de la variable del bucle exterior — un patrón muy poderoso que aparece constantemente.
Cuidado con la complejidad
Un único bucle sobre n elementos se ejecuta n veces. Un bucle anidado dentro de él se ejecuta n × n = n² veces. Tres bucles anidados se ejecutan n³ veces. Para n pequeño esto no importa; para n grande importa mucho:
| n | n² | n³ |
|---|---|---|
| 10 | 100 | 1,000 |
| 100 | 10,000 | 1,000,000 |
| 1,000 | 1,000,000 | 1,000,000,000 |
Si tu bucle anidado recorre un conjunto de datos grande, pregúntate si realmente necesitas el bucle interior. Una búsqueda en un HashMap a menudo reemplaza un bucle de búsqueda interior y transforma O(n²) en O(n).
break y continue solo afectan al bucle interior
Vimos esto en break y continue: sin una etiqueta, ambos aplican solo al bucle más interno. Para salir del bucle exterior o saltar su iteración desde dentro del interior, usa un break o continue con etiqueta — consulta sentencias etiquetadas.
Un ejemplo práctico
Qué viene a continuación
Cuando necesites usar break o continue en un bucle exterior desde dentro de uno interior, las sentencias etiquetadas te ofrecen una forma limpia de hacerlo.