Introducción
Contenido
Las declaraciones condicionales y los bucles son una herramienta muy importante en la programación. No hay muchas cosas que podamos hacer con código que solo se pueda ejecutar línea por línea.
Eso es lo que significa «control de flujo»: guiar la ejecución de nuestro programa, en lugar de dejar que se ejecute línea por línea independientemente de cualquier factor interno o externo. Cada lenguaje de programación admite alguna forma de control de flujo, si no explícitamente a través de if
sy for
s o declaraciones similares, entonces implícitamente nos da las herramientas para crear tales construcciones, es decir, los lenguajes de programación de bajo nivel generalmente logran ese efecto con una gran cantidad de go-to
comandos.
Los bucles eran un concepto que se usaba mucho antes de que la programación de computadoras existiera, pero la primera persona en usar un bucle de software fue Ada Lovelace, comúnmente conocida por su apellido de soltera, Byron, mientras calculaba Números de Bernoulli, allá por el siglo XIX.
En Java, hay varias formas de controlar el flujo del código:
- declaraciones if y if-else
- cambiar declaraciones
- declaraciones while y do-while
- bucles for y for-each
break
ycontinue
declaraciones
romper
los break
declaración es una de las «declaraciones de salto» de Java, ya que transfiere la ejecución del código a otra parte del código. Ya hemos visto el break
palabra clave utilizada en la declaración de cambio. Lo revisaremos aquí, junto con otros casos de uso:
- Se puede utilizar para detener la ejecución de un
switch
caso de declaración, en lugar de dejar que continúe ejecutando código para los siguientes casos también - Se puede usar para salir de un bucle antes de que haya terminado todas sus iteraciones, o como una forma de salir de bucles infinitos creados a propósito.
- Se puede utilizar como una forma aceptable de la declaración «ir a» cuando tenemos varios bucles anidados.
Los dos primeros son relativamente similares, ya que ambos se utilizan para finalizar prematuramente la ejecución de uno o más bloques de código:
// Finding at which index element a is in an array
int[] arr = {1,2,3,4,5,6};
int foundAt = -1;
int a = 4;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
if (arr[i] == a) {
foundAt = i;
break;
}
}
if (foundAt != -1)
System.out.println(a + " was found at index " + foundAt);
else System.out.println(a + " wasn't found in the array");
Salida:
1
2
3
4
4 was found at index 3
Como podemos ver, el for
bucle ejecutado como de costumbre hasta que se encontró con el break
declaración, en cuyo punto Java dejó de ejecutar el ciclo y continuó la ejecución en la primera línea después de la for
lazo.
Aquí hay otro ejemplo:
Scanner s = new Scanner(System.in);
while (true) {
System.out.println("Do you wish to exit the infinite loop? Y/N");
if (s.hasNext()) {
String answer = s.next();
if (answer.equals("Y") || answer.equals("y"))
break;
}
}
Este bucle seguirá preguntando al usuario si desea salir del bucle hasta que responda con los caracteres apropiados, donde salimos del bucle usando break
, o terminar el programa con Ctrl + C
.
Por defecto el break
declaración solo sale del bucle más interno en el que se encuentra.
Si quisiéramos encontrar la primera posición en la que se puede encontrar cierto elemento en una matriz, y quisiéramos break
fuera de los bucles tan pronto como lo encontramos (similar al ejemplo con una matriz anterior), escribir lo siguiente no funcionaría:
int[][] matrix = {{1,2,3},{4,5,6},{7,8,9}};
int foundAtI = -1;
int foundAtJ = -1;
int a = 4;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
if (matrix[i][j] == a) {
foundAtI = i;
foundAtJ = j;
break;
}
}
System.out.println();
}
System.out.println();
if (foundAtI != -1)
System.out.println(a + " was found at indices [" + foundAtI + "," + foundAtJ + "]");
else System.out.println(a + " wasn't found in the matrix");
Salida:
1 2 3
4
7 8 9
4 was found at indices [1,0]
Podemos ver que el bucle continuó ejecutándose incluso después de encontrar 4 en la matriz, después de tartamudear en la fila en la que se encontraba 4. Esto es porque el break
solo salió del bucle más interno, es decir, dejó de recorrer la fila actual y pasó a la siguiente. Además, nuestra tarea era encontrar la primera aparición de 4 en la matriz, y de esta forma devolveríamos la última aparición de 4 en nuestra matriz.
Aquí es donde entran en juego las declaraciones etiquetadas, que veremos a continuación.
Declaraciones etiquetadas
Las declaraciones etiquetadas se pueden utilizar junto con break
o continue
declaraciones para simular una go-to
.
Las etiquetas se pueden aplicar a cualquier bloque de código entre {}
, for
, for-each
, while
, do-while
, if
y switch
declaraciones, así como expresiones, asignaciones, return
declaraciones, try
bloques, y throw
declaraciones. Luego los usamos con el break
y continue
declaraciones.
Las etiquetas funcionan aplicando un identificador a una construcción:
Identifier : Construct
Como:
someLoop: for (int i = 0; i < 100; i++) {}
someLabel: {
int i = 10;
}
Luego podemos recurrir a estas declaraciones etiquetadas a través de un break
o continue
. Por ejemplo, aquí hemos etiquetado nuestro bucle externo como simplemente outer
. Para salir de dos o más bucles anidados, break
el bucle exterior llamando a la etiqueta:
outer: for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
if (matrix[i][j] == a) {
foundAtI = i;
foundAtJ = j;
break outer;
}
}
System.out.println();
}
El uso de este ciclo etiquetado en lugar del ciclo en el ejemplo anterior produce el resultado y el comportamiento correctos:
1 2 3
4
4 was found at indices [1,0]
No puedes usar break label
Si el break
no se encuentra dentro de un bloque de código designado por esa etiqueta o provocará un error durante la compilación.
Seguir
los continue
declaración simplemente omite el resto de la iteración actual y pasa a la siguiente. Es útil cuando queremos omitir iteraciones completas (o parte de) que cumplen ciertas condiciones, especialmente si tienen un alto rendimiento.
Para while
bucle, «omitir» el resto de la iteración significa volver directamente a verificar la condición antes de la siguiente iteración, y para un for
bucle esto significa ir a la parte «paso» del for
loop (la parte donde normalmente incrementamos / decrementamos la variable de control) y luego verificamos la condición antes de la siguiente iteración.
continue
se usa generalmente con un if
declaración -> lo haremos continue
si se cumple una determinada condición. Usamos esto if
para ejecutar el resto de la iteración solo si no se cumple la condición y omitir el uso continue
. Por ejemplo
// We want to print every number from 1 to 20, except those divisible by 3
for (int i = 1; i <= 20; i++) {
if (i % 3 == 0)
continue;
System.out.println(i);
}
los continue
en nuestro ejemplo podría evitarse fácilmente utilizando un if
declaración, principalmente imprimiendo el número si i % 3 != 0
es cierto, de lo contrario no hace nada.
Consejos generales sobre ambos break
y especialmente) continue
es intentar usarlos principalmente al comienzo de las iteraciones como alguna forma de condiciones previas que estamos verificando. Usando un continue
en algún lugar en el medio de la iteración es una excelente manera de causar errores que te llevarán un tiempo resolver.
Por supuesto, también puedes usar continue
con declaraciones etiquetadas:
start: for (int i = 0; i < 10; i++) {
System.out.println();
for (int j = 0; j < 10; j++) {
if (j >= i)
continue start;
}
System.out.println("Since j will always be equal to or more than i, the 'start' loop will continue running indefinitely, and this piece of code will never run.");
}
Conclusión
El control de flujo en el código es esencial en casi todas las aplicaciones. Las declaraciones que alteran el flujo del código son bloques de construcción fundamentales y cada desarrollador aspirante debe tener el control total / ser consciente de cómo funcionan.
Utilizando el break
y continue
declaraciones, los desarrolladores de Java pueden simular go-to
declaraciones y romper ciertos bucles si es necesario.