- Aprender
- Informática
- Programación
- Programación orientada a objetos con Java
- Condiciones y bucles en Java
Condiciones y bucles en Java
if, cadenas de condiciones else if y expresiones switch, y repite sentencias con bucles while, do-while y for, utilizando break y continue cuando sean útiles. Después, aplica los patrones habituales de bucles para contar, sumar, calcular medias, encontrar el valor máximo, buscar e imprimir tablas, y comprueba tus bucles siguiendo su ejecución paso a paso.PrincipianteUnidad 2 de 11 del curso Curso de Programación orientada a objetos con Java
Lo que aprenderás
- Construye condiciones verdaderas o falsas a partir de comparaciones y combínalas con operadores lógicos para que un programa compruebe exactamente la situación que quieres.
- Compara valores y almacena los resultados como booleanosUtiliza los seis operadores de comparación con números y caracteres, guarda los resultados en variables
booleany compara correctamente cadenas y números decimales. - Combina condiciones con &&, || y !Une y niega condiciones con los operadores lógicos, predice sus resultados con tablas de verdad y utiliza la evaluación en cortocircuito y las leyes de De Morgan para escribir comprobaciones correctas y legibles.
- Compara valores y almacena los resultados como booleanos
- Haz que un programa ejecute distintas sentencias según las condiciones, desde un único
ifhasta cadenas de condicioneselse if, el operador condicional yswitch.- Ejecuta código de forma condicional con if y elseEscribe sentencias
ifeif-elsecon bloques correctos, evita los errores clásicos de llaves, punto y coma y ámbito, y anida decisiones o elige un valor con el operador condicional. - Elige uno de varios casos con cadenas de condiciones else-ifUtiliza cadenas de condiciones
else ifpara elegir exactamente uno de varios resultados, ordena correctamente las condiciones y prueba los límites para que ningún valor quede en un hueco o en dos casos. - Selecciona según un valor con switchUtiliza sentencias
switchy expresionesswitchpara elegir según el valor de una variable, con casos de flecha, varias etiquetas por caso,defaultyyield, y reconoce la continuación entre casos en la forma antigua con dos puntos.
- Ejecuta código de forma condicional con if y else
- Escribe bucles
while,do-whileyforque se ejecuten el número adecuado de veces y se detengan cuando deban, y controla su ejecución conbreakycontinue.- Repite mientras se cumpla una condición con whileEscribe bucles
whileque comiencen, se actualicen y se detengan correctamente, utilizawhile (true)conbreakpara repeticiones sin duración predeterminada y sigue la ejecución de un bucle paso a paso. - Ejecuta el cuerpo al menos una vez con do-whileUtiliza el bucle
do-whilecuando el cuerpo deba ejecutarse antes de la primera comprobación, como en las validaciones de entrada y los menús, y evita sus errores de ámbito y punto y coma. - Recorre rangos mediante un contador con bucles forEscribe bucles
forque cuenten hacia arriba, hacia abajo y con distintos incrementos, predice cuántas veces se ejecutan, evita errores de una unidad y elige el tipo de bucle adecuado para cada tarea. - Sal de bucles u omite iteraciones con break y continueTermina un bucle antes de tiempo con
break, omite el resto de una pasada concontinue, sal de bucles anidados con unbreakcon etiqueta y mantén fáciles de seguir los bucles con salidas anticipadas.
- Repite mientras se cumpla una condición con while
- Reconoce y combina los patrones habituales de bucles: contar y sumar, encontrar valores extremos, buscar, procesar dígitos y anidar bucles, y comprueba los bucles siguiendo su ejecución y probándolos.
- Cuenta valores, súmalos y calcula su mediaUtiliza contadores y acumuladores con entrada controlada por un centinela, calcula medias y porcentajes sin errores de división entera y protégete frente a entradas vacías y desbordamientos.
- Encuentra valores extremos, realiza búsquedas y procesa dígitosHaz seguimiento del valor máximo o mínimo encontrado hasta el momento, busca con un indicador booleano o una salida anticipada, comprueba si algún valor o todos cumplen una condición y descompón números dígito a dígito.
- Anida bucles, sigue su ejecución y pruébalosEscribe bucles anidados para tablas y patrones, predice cuántas veces se ejecuta el cuerpo interior, sigue la ejecución de bucles con una tabla y pruébalos con casos extremos para detectar errores de una unidad y bucles infinitos.
- Cuenta valores, súmalos y calcula su media
Guía de estudio de Condiciones y bucles en Java
1Construye condiciones verdaderas o falsas
Una condición convierte una pregunta sobre los datos del programa en un valor verdadero o falso. Las comparaciones permiten preguntar si un número alcanza un límite o si un texto coincide con un comando; los operadores lógicos permiten unir esas comprobaciones. Lee las partes de una condición en el orden en que Java las evalúa y después comprueba el resultado combinado. Esto permite expresar un rango, una excepción o una condición de protección para una división segura sin que un pequeño error de operador cambie la regla.
1.1 Comparaciones y valores booleanos
Una condición tiene tipo boolean: produce true o false. Java necesita ese resultado explícito en una condición de if o de bucle. Un entero por sí solo no es una condición, por lo que while (count) no compila; count > 0 plantea una pregunta clara de verdadero o falso.
Compara números y caracteres
| Operador | Pregunta |
|---|---|
< | ¿Es menor el valor de la izquierda? |
<= | ¿Es menor o igual? |
> | ¿Es mayor? |
>= | ¿Es mayor o igual? |
== | ¿Son iguales los valores? |
!= | ¿Son distintos los valores? |
Con int a = 7; y int b = 10;, a < b y a != b son true, mientras que a >= b es false. Se pueden comparar tipos numéricos distintos: 3 == 3.0 es true después de que Java convierta el entero a un double mediante ampliación.
Una comparación de char utiliza números de código Unicode. Por ejemplo, 'a' < 'b' es true. También lo es 'Z' < 'a': sus códigos son 90 y 97. Todas las letras mayúsculas ASCII de A a Z preceden a las minúsculas de a a z en este orden.
Almacena una respuesta útil
int age = 17;
boolean isAdult = age >= 18;
System.out.println(isAdult);
La comparación da false, que se almacena en isAdult y después se imprime. Un nombre significativo permite que el código posterior diga directamente if (isAdult).
Distingue la asignación de la comparación. = almacena un valor; == compara valores. Para un entero, if (x = 5) falla porque la asignación produce un entero. Para un booleano, if (done = true) compila, asigna true a done y ejecuta la rama. Para comprobar el indicador existente, escribe if (done).
Compara texto y decimales calculados
Utiliza command.equals("quit") para comparar los caracteres de una cadena. El texto introducido como «quit» coincide; «Quit» no. Utiliza equalsIgnoreCase cuando las mayúsculas y minúsculas no deban importar, y !command.equals("quit") para comprobar si el texto es distinto. El operador == pregunta si las cadenas hacen referencia al mismo objeto, por lo que no es adecuado para comparar el contenido de la entrada del usuario.
La representación binaria en coma flotante no puede almacenar exactamente muchas fracciones decimales. 0.1 + 0.2 produce 0.30000000000000004, por lo que 0.1 + 0.2 == 0.3 es false. Una comparación con tolerancia comprueba cuánto difieren los valores calculados:
double sum = 0.1 + 0.2;
boolean closeEnough = Math.abs(sum - 0.3) < 1e-9;
Aquí Math.abs hace que la diferencia no sea negativa; la pequeña diferencia está por debajo de 1e-9, por lo que closeEnough es true. Elige una tolerancia adecuada a la precisión que requiere el cálculo. Las comparaciones exactas de valores int no tienen el problema de redondeo de la coma flotante.
Comprueba la divisibilidad y los rangos
n % 3 == 0 comprueba si un entero es divisible por 3. Para los números impares, utiliza n % 2 != 0: la comprobación incluye los valores impares negativos, ya que -7 % 2 es -1.
Escribe cada lado de una comprobación de rango por separado: 0 < x && x < 10. Java no puede leer 0 < x < 10 como una cadena matemática: su primera comparación ya produce un booleano que no puede compararse con 10.
Puntos clave
- Una condición debe producir un
boolean. - Utiliza
=para asignar y==para comparar valores numéricos. - Compara el contenido de las cadenas con
equalsoequalsIgnoreCase. - Compara los decimales calculados con una tolerancia adecuada.
- Utiliza
n % 2 != 0para los enteros impares, incluidos los negativos.
1.2 Condiciones combinadas y evaluación en cortocircuito
Los operadores lógicos combinan condiciones completas de verdadero o falso. Lee una condición combinada como una regla sobre los datos y después prueba valores que deban cumplirla y valores que no.
Une y niega comprobaciones
&& significa y: ambas partes deben ser verdaderas. || significa o: al menos una parte debe ser verdadera, incluso cuando lo son ambas. ! significa no e invierte un valor booleano.
| p | q | p && q | p || q |
| --- | --- | --- | --- |
| true | true | true | true |
| true | false | false | true |
| false | true | false | true |
| false | false | false | false |
Una temperatura agradable de 18 a 24 °C necesita ambos límites: temp >= 18 && temp <= 24. Estar fuera de ese intervalo significa temp < 18 || temp > 24. Unir los límites interiores con || acepta cualquier número: por debajo de 18 la comprobación del límite superior es verdadera y por encima de 24 la comprobación del límite inferior es verdadera.
Cada operando debe ser una expresión booleana. Escribe x == 1 || x == 2, porque x == 1 || 2 coloca un entero donde se requiere un booleano. Para un entero, !x > 5 no es válido; !(x > 5) niega toda la comparación.
Evalúa solo lo necesario
Java evalúa && y || de izquierda a derecha y aplica cortocircuito cuando la parte izquierda determina el resultado. Con &&, un lado izquierdo falso omite el lado derecho. Con ||, un lado izquierdo verdadero lo omite.
int total = 36;
int count = 0;
boolean largeAverage = count != 0 && total / count > 10;
La primera comparación es falsa, por lo que se omite la división y largeAverage pasa a ser false. Invierte los operandos y la división ocurre antes de la protección; la división entera entre cero lanza una ArithmeticException. Coloca la comprobación de seguridad antes del cálculo que protege.
Haz visible la agrupación
De mayor a menor precedencia, los operadores pertinentes son !, las comparaciones relacionales (<, <=, >, >=), las comparaciones de igualdad (==, !=), && y después ||. Así, a || b && c se agrupa como a || (b && c). Cuando a es verdadero y b y c son falsos, esa expresión es verdadera; (a || b) && c es falsa. Los paréntesis muestran qué regla quieres aplicar.
Las leyes de De Morgan trasladan una negación a través de una condición combinada:
!(p && q)equivale a!p || !q.!(p || q)equivale a!p && !q.
Niega cada parte e intercambia el operador que las une. Aplicar esto al rango de temperaturas da !(temp >= 18 && temp <= 24) equivalente a temp < 18 || temp > 24.
Expresa una regla con una excepción
Un año bisiesto del calendario gregoriano es divisible por 4, salvo que un año de siglo debe ser divisible por 400:
boolean leap = (year % 4 == 0 && year % 100 != 0)
|| year % 400 == 0;
La primera parte acepta 2024. Rechaza 1900 porque 1900 es un año de siglo; la comprobación final acepta 2000 porque es divisible por 400. El año 2026 no cumple ninguna de las dos partes.
Los booleanos con nombre ayudan a leer con claridad comprobaciones más largas, como isWeekend || isHoliday. Para dos booleanos, ^ es la disyunción exclusiva: exactamente un operando debe ser verdadero, igual que con !=. Los operadores simples & y | también calculan la conjunción y la disyunción booleanas, pero evalúan ambos operandos; utiliza && y || para condiciones con cortocircuito.
Puntos clave
&&requiere ambas condiciones;||requiere al menos una.- Una condición de protección con cortocircuito va antes de la expresión que protege.
&&tiene mayor precedencia que||; los paréntesis pueden cambiar el resultado.- Las leyes de De Morgan niegan ambas partes e intercambian
&&por||. - Cada lado de un operador lógico debe ser una expresión booleana completa.
- Los operadores simples
&y|evalúan ambos operandos.
2Elige la ruta que sigue un programa
Una decisión dirige la ejecución por una ruta seleccionada. Una sola comprobación puede activar una acción, dos ramas pueden elegir entre dos acciones y una cadena puede asignar un resultado entre varios rangos. Cuando la elección depende de valores exactos de una variable, switch ofrece otra forma clara. Seguir la ruta significa comprobar a qué condiciones se llega, qué rama se ejecuta y qué variables siguen disponibles después.
2.1 Ramas, bloques y elección de valores
Un if ejecuta un bloque cuando su condición es verdadera. Un if con un else elige exactamente uno de dos bloques. Cuando termina el bloque elegido, la ejecución continúa con la siguiente sentencia.
Elige una ruta
int age = 16;
if (age >= 18) {
System.out.println("Adult ticket");
} else {
System.out.println("Youth ticket");
}
System.out.println("Next customer");
La condición es falsa, por lo que la salida es «Youth ticket», seguida de «Next customer». La última sentencia no pertenece a ninguna de las dos ramas. Pon la condición booleana entre paréntesis y las sentencias de cada rama entre llaves.
Sin llaves, solo la siguiente sentencia pertenece a un if. La sangría no agrupa el código. En este ejemplo incorrecto, el segundo mensaje aparece para cualquier puntuación:
if (score < 50)
System.out.println("Not passed");
System.out.println("Try again");
Las llaves alrededor de ambas sentencias de impresión hacen que ambas sean condicionales. Otro error es un punto y coma inmediatamente después de la condición: if (x > 10); tiene un cuerpo vacío. Un bloque que lo sigue se ejecuta de forma independiente y un else después de ese bloque independiente no tiene un if correspondiente.
Mantén disponible un resultado
Una variable declarada dentro de un bloque solo es visible dentro de ese bloque. Declara un resultado antes de las ramas cuando el código posterior lo necesite:
String ticket;
if (age >= 18) {
ticket = "Adult ticket";
} else {
ticket = "Youth ticket";
}
System.out.println(ticket);
Ambas rutas posibles asignan un valor a ticket, por lo que imprimirla después es válido. Si solo la rama verdadera le asignara un valor, Java rechazaría la lectura posterior: la variable podría no haberse inicializado. Declarar ticket por separado dentro de cada rama también dejaría sin una ticket disponible después de la decisión.
Coloca una decisión dentro de otra
Un if anidado ejecuta su comprobación solo cuando la ejecución llega a la rama que lo contiene:
if (hasTicket) {
if (age < 12) {
System.out.println("Child seat");
} else {
System.out.println("Standard seat");
}
} else {
System.out.println("Buy a ticket first");
}
Una persona sin entrada llega al else externo; se omite la comprobación de edad. Si ambas comprobaciones anidadas solo protegen la misma acción y ninguna tiene un else, pueden convertirse en if (hasTicket && age < 12).
La regla del else ambiguo vincula un else al if sin pareja más cercano. Sin llaves, alinearlo visualmente con un if externo no cambia esa regla. Para una comprobación externa de x positivo seguida de una comprobación interna de y positivo, el siguiente else pertenece a la comprobación de y. Se necesitan llaves alrededor de toda la decisión interna cuando el else debe pertenecer a la comprobación externa.
Elige un valor con ?:
El operador condicional elige uno de dos valores:
int n = 7;
String label = n % 2 == 0 ? "even" : "odd";
La condición es falsa, por lo que la expresión da «odd». Su forma es condition ? valueIfTrue : valueIfFalse. Utilízalo para elegir un valor de forma breve; utiliza un if cuando las ramas realicen varias acciones. Las expresiones condicionales anidadas pronto dificultan seguir la ruta elegida.
Puntos clave
- Las llaves agrupan todas las sentencias que pertenecen a una rama.
- Un
elsese vincula alifsin pareja más cercano. - Un resultado necesario después de una decisión debe estar en el ámbito y tener un valor asignado en cada ruta que llegue a su uso.
?:elige un valor entre dos expresiones.
2.2 Casos ordenados y valores límite
Una cadena de condiciones else if comprueba las condiciones en orden y selecciona la primera verdadera. Una vez ejecutada esa rama, se omiten las condiciones restantes. Un else final maneja los valores restantes; sin él, la cadena puede no realizar ninguna acción.
Ordena umbrales que se solapan
Para puntuaciones de 0 a 100, comprueba primero la calificación más alta:
String grade;
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 70) {
grade = "C";
} else if (score >= 60) {
grade = "D";
} else {
grade = "F";
}
Para 85, la primera comprobación falla y la segunda se cumple. El programa asigna «B» sin comprobar los umbrales restantes. Llegar a score >= 80 ya significa que la puntuación es inferior a 90, por lo que no se necesita un límite superior adicional.
Si score >= 60 apareciera primero, todas las puntuaciones aprobadas recibirían «D». Trabaja desde el caso coincidente más restrictivo hacia los más amplios. Esta regla de orden importa porque varias condiciones pueden ser verdaderas aunque solo se ejecute una rama.
Maneja primero el caso combinado
FizzBuzz tiene un caso especial en el que se solapan dos reglas: los múltiplos de 3 y de 5 necesitan «FizzBuzz». Comprueba ese caso antes de cualquiera de las comprobaciones individuales de divisibilidad:
if (n % 15 == 0) {
System.out.println("FizzBuzz");
} else if (n % 3 == 0) {
System.out.println("Fizz");
} else if (n % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(n);
}
La comprobación % 15 == 0 acepta 30; 9 llega a «Fizz», 10 llega a «Buzz» y 7 llega a la rama final. Empezar con % 3 == 0 aceptaría 30 demasiado pronto e imprimiría solo «Fizz».
Elige un resultado o varias acciones
Las sentencias if separadas son decisiones independientes. Con x = 15, un if (x > 10) puede imprimir «big» y un if (x > 0) posterior también puede imprimir «positive». Unirlas con else if hace que la segunda comprobación sea inalcanzable siempre que la primera sea verdadera. Utiliza comprobaciones independientes cuando puedan ser necesarias ambas acciones; utiliza una cadena para seleccionar un resultado.
Comprueba los extremos y los valores no válidos
Una cadena para temperaturas enteras con temp < 10, después temp > 10 && temp < 25 y después temp >= 25 omite exactamente 10. Sustituye la segunda comprobación por temp < 25: llegar a ella ya significa que la primera comprobación falló, por lo que el valor es al menos 10. Un else final maneja entonces 25 y los valores superiores.
Para cada umbral, prueba el valor inmediatamente inferior, el propio umbral y el valor inmediatamente superior. Para la cadena de puntuaciones, 89, 90 y 91 revelan si el límite de A está incluido correctamente. Prueba también los límites generales.
Valida una puntuación antes de calificarla: coloca score < 0 || score > 100 primero e informa allí con «Invalid score». Las ramas posteriores operan entonces solo con puntuaciones válidas; 150 no puede recibir «A» por accidente. La validación es un primer caso independiente, no una corrección después de haber elegido la calificación.
Puntos clave
- La primera condición verdadera de una cadena selecciona la única rama que se ejecuta.
- Coloca los casos que se solapan más restrictivos antes que los más amplios.
- Utiliza sentencias
ifseparadas cuando puedan aplicarse varias acciones. - Prueba los valores en cada umbral y junto a él.
- Rechaza las entradas no válidas antes de clasificar las válidas.
2.3 Casos switch y resultados de expresiones
Un switch selecciona un caso comparando un valor con etiquetas fijas. Es adecuado para comandos con nombre y opciones numeradas. Utiliza una cadena de condiciones else if cuando la elección dependa de un rango o de varias variables.
Busca valores exactos
Un switch por valor acepta selectores char, byte, short, int, sus tipos envoltorio, String y enum. Sin funcionalidades preliminares, los selectores long, float, double y boolean no están permitidos. Las etiquetas deben ser constantes: una condición como score >= 90 no es una etiqueta de valor.
switch (day) {
case 1, 2, 3, 4, 5 -> System.out.println("Weekday");
case 6, 7 -> System.out.println("Weekend");
default -> System.out.println("Invalid day");
}
Un caso con flecha ejecuta solo su propio código, sin continuar al siguiente caso. Las comas agrupan varias etiquetas para una acción. Un día con valor 6 imprime «Weekend»; un día con valor 9 no coincide con ningún valor enumerado e imprime «Invalid day».
Las etiquetas String coinciden con contenido exacto y distinguen mayúsculas de minúsculas. El comando «Start» no coincide con case "start". Una etiqueta duplicada es un error de compilación y un mismo switch no puede mezclar casos con flecha y casos con dos puntos.
Produce un valor
Una expresión switch calcula un resultado:
int days = switch (month) {
case 1, 3, 5, 7, 8, 10, 12 -> 31;
case 4, 6, 9, 11 -> 30;
case 2 -> 28;
default -> 0;
};
En un año no bisiesto, el mes 9 da 30, el mes 2 da 28 y el mes no válido 13 da 0. El punto y coma después de la llave de cierre termina la declaración de la variable.
Una expresión debe ser exhaustiva: cada valor posible del selector debe tener un resultado. Para estos ejemplos con int y String, incluye default. Una sentencia switch por valor puede omitir default; un valor sin coincidencia no ejecuta ningún caso. Una expresión que produce un valor no puede simplemente omitir su resultado.
Proporciona un resultado a un bloque con yield
Un caso que calcula antes de elegir su valor necesita un bloque:
int days = switch (month) {
case 2 -> {
boolean leap = (year % 4 == 0 && year % 100 != 0)
|| year % 400 == 0;
yield leap ? 29 : 28;
}
case 4, 6, 9, 11 -> 30;
case 1, 3, 5, 7, 8, 10, 12 -> 31;
default -> 0;
};
yield proporciona el valor del caso a la expresión switch. Febrero da 29 en 2024 y 28 en 2026. Una sola expresión después de una flecha, como case 2 -> 28;, no necesita yield.
Interpreta la forma antigua con dos puntos
switch (level) {
case 1:
System.out.println("Bronze");
case 2:
System.out.println("Silver");
break;
case 3:
System.out.println("Gold");
break;
}
Para el nivel 1, la ejecución entra en el primer caso y continúa en el segundo, imprimiendo tanto «Bronze» como «Silver». Esto es la continuación entre casos: una etiqueta con dos puntos no detiene la ejecución. break termina el switch. Las etiquetas consecutivas con dos puntos pueden compartir una acción de forma intencionada; la falta de un break después de una acción puede ejecutar la siguiente por accidente.
Un switch de char puede agrupar 'a', 'e', 'i', 'o', 'u' en un resultado «vowel», con default dando «other». El mismo principio de valor exacto se aplica a caracteres, comandos y opciones numéricas.
Puntos clave
- Utiliza
switchpara etiquetas fijas de un selector. - Los casos con flecha no continúan al siguiente caso.
- Una expresión switch debe producir un resultado para cada posible valor del selector.
- Un caso con bloque proporciona el resultado de su expresión con
yield. - Un caso con dos puntos puede continuar al siguiente sin
break. - Los casos String coinciden con contenido exacto y distinguen mayúsculas de minúsculas.
3Controla la repetición y la parada
La repetición depende tanto de una condición como de un cambio en el estado del programa. Sigue un bucle desde sus valores iniciales, pasando por su comprobación, cuerpo y actualización, para ver cuándo se detiene. Las tres formas de bucle colocan estas partes en lugares distintos: antes del cuerpo, después de él o juntas en una cabecera. Las salidas anticipadas y las pasadas omitidas añaden opciones útiles, pero también hacen que sea conveniente seguir con cuidado el orden de ejecución.
3.1 Comprobaciones del bucle while y cambios de estado
Un bucle while comprueba su condición antes de cada pasada. Si la condición es verdadera, Java ejecuta el cuerpo y vuelve a la comprobación. Si es falsa, la ejecución continúa después del bucle. Una primera comprobación falsa significa cero pasadas.
Sigue el inicio, la comprobación, el cuerpo y la actualización
int i = 1;
while (i <= 5) {
System.out.println(i);
i++;
}
El valor inicial es 1. Cada pasada imprime el valor actual y después lo incrementa. La quinta pasada imprime 5 y cambia i a 6. La siguiente comprobación es falsa, por lo que el bucle termina. Hay cinco ejecuciones del cuerpo, pero seis comprobaciones de la condición: una antes de cada pasada y una comprobación final falsa.
Un bucle de conteo necesita un valor inicial, una comprobación y una actualización que avance hacia la parada. Omite i++ y este bucle imprimirá 1 para siempre. Un punto y coma añadido por error es otra trampa: en while (i <= 5);, la sentencia vacía es el cuerpo. Cuando i empieza dentro del rango, nunca se llega al bloque posterior y este no puede actualizarlo.
Detente cuando se cruce un límite
La igualdad suele ser una comprobación de parada frágil. Empezar en 0 y sumar 3 recorre 0, 3, 6, 9, 12 y así sucesivamente. La comprobación i != 10 no puede detectar que se cruza 10 porque se salta 10. La comprobación i < 10 termina después de procesar 9. Elige un límite que se ajuste a la dirección de la actualización.
Algunos bucles se repiten un número desconocido de veces. Por ejemplo:
int amount = 1;
int days = 0;
while (amount < 1000) {
amount *= 2;
days++;
}
Cada pasada duplica la cantidad y cuenta un día. Después de nueve pasadas es 512; después de diez es 1024. La comprobación falsa en 1024 deja days igual a 10. Un bucle puede terminar por encima de su umbral cuando la actualización avanza con incrementos mayores.
Lee antes de decidir si detenerte
while (true) {
String line = scanner.nextLine();
if (line.equals("stop")) {
break;
}
System.out.println("You wrote: " + line);
}
Aquí scanner es el Scanner de entrada. El bucle lee una línea, comprueba si es «stop» y solo muestra de nuevo las líneas normales. El comando de parada se consume, pero no se procesa. while (true) necesita una salida alcanzable para terminar; un bucle que sigue repitiéndose sin salir es un bucle infinito.
Sigue los cambios de estado
Considera un producto:
int n = 3;
int product = 1;
while (n > 0) {
product *= n;
n--;
}
| Momento | product | n |
|---|---|---|
| Antes del bucle | 1 | 3 |
| Después de la pasada 1 | 3 | 2 |
| Después de la pasada 2 | 6 | 1 |
| Después de la pasada 3 | 6 | 0 |
La multiplicación utiliza el valor anterior de n y el decremento va después. Mover el decremento antes de la multiplicación cambiaría los valores que se multiplican.
Declara un resultado acumulado antes del bucle para que se conserve de una pasada a otra. Una variable declarada dentro del cuerpo se crea de nuevo cada vez que la ejecución llega a su declaración. Imprime dentro del cuerpo para ver los resultados intermedios; imprime después de la llave de cierre para mostrar el resultado final una sola vez.
Puntos clave
- Un bucle
whilepuede ejecutarse cero veces. - Sigue la condición antes de cada pasada, incluida la comprobación final falsa.
- Los bucles de conteo necesitan una actualización que avance hacia un límite de parada.
- Un comando de parada debe comprobarse antes de procesar su entrada.
- Mantén los resultados acumulados fuera del cuerpo del bucle.
3.2 Validaciones de entrada con do-while
Un bucle do-while ejecuta el cuerpo antes de comprobar si se necesita otra pasada. Utilízalo cuando la primera acción deba realizarse, por ejemplo, mostrar un menú o pedir un valor de entrada.
Comprueba después de la primera acción
int i = 10;
do {
System.out.println(i);
i++;
} while (i < 5);
El cuerpo imprime 10 e incrementa i hasta 11. Solo entonces Java comprueba i < 5. Es falso, por lo que no hay una segunda pasada. Un bucle while (i < 5) que empiece en 10 no imprimiría nada.
El punto y coma después del while (...) final es obligatorio. Cierra la sentencia do-while. Esto difiere del punto y coma accidental después de la cabecera de un while con comprobación previa, que crea un cuerpo de bucle vacío.
Repite mientras la entrada no sea válida
int rating;
do {
System.out.print("Rating (1-5): ");
rating = Integer.valueOf(scanner.nextLine());
} while (rating < 1 || rating > 5);
El mensaje aparece antes de la primera comprobación, por lo que el usuario puede proporcionar el valor que se comprueba. Con la entrada 7, después 0 y después 4, las dos primeras condiciones son verdaderas y provocan otra solicitud. La última condición es falsa, por lo que el bucle termina con rating igual a 4.
La condición describe la continuación, no la aceptación. Una valoración válida cumple rating >= 1 && rating <= 5. El bucle se repite mientras esa afirmación sea falsa, lo que las leyes de De Morgan reescriben como rating < 1 || rating > 5. Una conjunción entre estos límites exteriores nunca sería verdadera: un número no puede ser menor que 1 y mayor que 5 al mismo tiempo.
Declara la variable comprobada antes del bloque
La llave de cierre termina el ámbito del cuerpo antes de que se evalúe la condición. Por tanto, una declaración como int rating dentro del bloque do no estaría disponible en la condición final. Declárala antes de do y asigna la entrada dentro del cuerpo. La asignación siempre se ejecuta antes de la primera comprobación.
La misma ubicación importa cuando el valor aceptado se utiliza después. rating permanece en el ámbito después de todo el bucle y ahora contiene el último valor leído.
Mantén abierto un menú
String choice;
do {
System.out.println("a: show status, q: quit");
choice = scanner.nextLine();
if (choice.equals("a")) {
System.out.println("Ready");
}
} while (!choice.equals("q"));
Cada pasada muestra el menú y lee una elección. Introducir «a» imprime «Ready» y repite. Introducir «q» omite la acción y termina en la condición. Un comando desconocido también repite porque no es «q».
Cuando su cuerpo no contiene ningún continue dirigido al bucle, un do-while puede reescribirse como while (true) con un break basado en la condición negada al final. Un continue requiere especial cuidado en esa reescritura: en el do-while original salta a la condición, mientras que en un bucle while-true salta al principio y puede omitir esa comprobación añadida al final.
Puntos clave
- El cuerpo de un do-while se ejecuta antes de su primera comprobación.
- El punto y coma final es obligatorio.
- Declara una variable fuera del cuerpo cuando la condición la necesite.
- Para validar la entrada, repite mientras el valor no sea válido.
3.3 Rangos y extremos de bucles for
Un bucle for agrupa el control de una tarea de conteo en una cabecera. Es útil cuando conoces el rango o el número de pasadas antes de que comience la repetición.
Lee la cabecera en orden de ejecución
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
La inicialización se ejecuta una vez y asigna 1 a i. Java comprueba i <= 5, ejecuta el cuerpo si es verdadero, ejecuta i++ y vuelve a la comprobación. La actualización está escrita en la cabecera, pero se ejecuta después del cuerpo. La comprobación final falsa termina el bucle.
Para el conteo habitual, i++ y ++i tienen el mismo efecto en la posición de actualización porque no se utiliza el valor de ninguna de las dos expresiones. Mantén los cambios del contador en la cabecera para que la secuencia sea fácil de predecir.
Elige los valores primero y último
| Cabecera | Valores utilizados por el cuerpo | Pasadas |
|---|---|---|
int i = 0; i < 5; i++ | De 0 a 4 | 5 |
int i = 0; i <= 5; i++ | De 0 a 5 | 6 |
int i = 10; i >= 1; i-- | De 10 a 1 | 10 |
int i = 0; i <= 20; i += 5 | 0, 5, 10, 15, 20 | 5 |
Para incrementos ascendentes de una unidad, con el final al menos igual al inicio, un extremo final excluido da final menos inicio pasadas; un extremo final incluido añade una. Los incrementos mayores requieren enumerar o contar los valores que realmente se alcanzan. Un bucle descendente debe comprobar en la dirección correspondiente: empezar en 10 con i <= 1 da cero pasadas.
Un error de una unidad incluye o excluye un extremo no deseado. Para imprimir del 1 al 10, i < 10 omite el 10; utiliza i <= 10. Comprueba el primer valor del cuerpo, el último valor del cuerpo y el primer valor que no cumple la condición.
Construye un resultado a lo largo de un rango
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println(sum);
El cuerpo suma cada entero una vez y termina con 5050. Un producto empieza de otra manera: inicializa product en 1 antes de multiplicar por los números del 1 al 5. Esto da 120; empezar en 0 dejaría el producto en 0 después de cada multiplicación.
Vigila el ámbito y los cuerpos vacíos
Un contador declarado en la cabecera existe durante todo ese bucle, pero no después de su llave de cierre. Decláralo antes si el código posterior necesita su valor final.
Un punto y coma inmediatamente después de la cabecera es un cuerpo vacío. En for (int i = 0; i < 3; i++);, la sentencia vacía se ejecuta tres veces. Un bloque posterior que imprime «Hello» se ejecuta una vez después del bucle, no tres. Las llaves van directamente después de la cabecera.
Se puede omitir cualquier parte de la cabecera. for (;;) { ... } no tiene condición de parada y se comporta como while (true); necesita una salida como break para terminar.
Selecciona el bucle más claro
| Tarea | Forma útil | Motivo |
|---|---|---|
| Recorrer un rango conocido | for | El inicio, el límite y el incremento están juntos. |
| Repetir hasta que cambie la entrada o el estado | while | La comprobación puede impedir la primera pasada. |
| Preguntar primero y después comprobar | do-while | La primera ejecución del cuerpo es necesaria. |
Las formas pueden expresar la misma repetición, pero las reescrituras deben conservar el orden de las comprobaciones y actualizaciones, incluido lo que omite un continue.
Puntos clave
- Un bucle for ejecuta la inicialización una vez y después la comprobación, el cuerpo y la actualización.
- Comprueba el inicio, el último valor incluido y el número de pasadas.
- Un contador declarado en la cabecera no está disponible después del bucle.
- Utiliza
forpara rangos,whilepara cambios de estado y do-while para una primera pasada obligatoria. - Un punto y coma después de una cabecera for crea un cuerpo vacío.
3.4 Salidas anticipadas y pasadas omitidas
Una salida anticipada puede detener la repetición en cuanto se complete su tarea. Una pasada omitida puede dejar fuera trabajo no deseado mientras el bucle continúa. Sigue con cuidado sus destinos: break y continue cumplen funciones distintas.
Termina una búsqueda con break
for (int n = 51; n <= 100; n++) {
if (n % 7 == 0) {
System.out.println(n);
break;
}
}
Los valores del 51 al 55 no cumplen la comprobación de divisibilidad. El siguiente valor, 56, se imprime y break sale del bucle inmediatamente. La actualización no se ejecuta después de ese break. Sin él, también se imprimirían múltiplos posteriores como 63 y 70.
Un break sin etiqueta se dirige al bucle o switch más cercano que lo contiene. La ejecución continúa después de esa estructura, no después de todo el programa.
Omite trabajo con continue
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
continue;
}
System.out.print(i + " ");
}
Para 3, 6 y 9, continue omite la sentencia de impresión. En un bucle for, la actualización de la cabecera sigue ejecutándose, seguida de la condición. La salida contiene 1, 2, 4, 5, 7, 8 y 10.
En un while o do-while, continue va a la condición. Se omite cualquier actualización situada después de él en el cuerpo. Si un contador while empieza en 0 y la primera acción es if (i % 3 == 0) { continue; }, nunca se llega a un i++ posterior en el cuerpo. El contador permanece en 0 y el bucle se repite para siempre. Mueve la actualización necesaria antes de cada ruta que se omita o utiliza una cabecera for para mantener la actualización automática.
Sal de bucles anidados de forma deliberada
Un break normal dentro de un bucle interno termina solo ese bucle interno. Una etiqueta puede nombrar un bucle externo como destino de salida:
outer:
for (int a = 1; a <= 10; a++) {
for (int b = 1; b <= 10; b++) {
if (a * b == 24 && a + b == 10) {
System.out.println("Found " + a + " and " + b);
break outer;
}
}
}
La búsqueda visita los pares en orden. Con a = 4 y b = 6, ambas comprobaciones se cumplen y el break con etiqueta sale de ambos bucles. continue outer pasaría, en cambio, a la actualización del bucle externo y después a su siguiente comprobación.
Distingue las salidas de switch de las salidas de bucle
En un bucle de menú que contiene un switch con dos puntos, break dentro de un caso termina el switch. No termina por sí mismo el bucle que lo rodea. Un patrón claro asigna false a un indicador del bucle en el caso de salida y después utiliza break para salir del switch. El bucle termina cuando su siguiente comprobación de la condición encuentra el indicador en falso. Los casos con flecha no necesitan break para evitar la continuación entre casos.
Un break sin etiqueta está permitido dentro de un bucle o switch; continue está permitido dentro de un bucle. Colocarlos en otro lugar hace que la compilación falle. Mantén la regla normal de parada en la condición del bucle cuando encaje ahí. Utiliza while (true) con un break cuando la comprobación de parada pertenezca de forma natural al punto posterior a la lectura de la entrada, pero anterior a su procesamiento. Varias salidas pueden ser útiles, pero cada ruta adicional añade estado que seguir al revisar la ejecución.
Puntos clave
breaksale de su destino inmediatamente.- Un
continueen un bucle for sigue ejecutando la actualización de la cabecera. - Un
continueen un bucle while puede omitir una actualización necesaria del cuerpo. - Una salida normal afecta a la estructura válida más cercana.
- Un break con etiqueta puede salir de un bucle externo.
- Un break de switch no sale directamente de un bucle que lo rodea.
4Construye y comprueba bucles útiles
Un bucle resulta útil cuando conserva solo la información que necesita un problema: un recuento, una suma acumulada, un mejor valor o un indicador que registra una coincidencia. Combinar esos pequeños patrones resuelve tareas de procesamiento de entrada y búsqueda. Los bucles anidados extienden la repetición a filas y columnas. Sigue los valores que cambian, mantén el estado en el ámbito adecuado y utiliza entradas vacías y casos límite para comprobar que el resultado describe todos los datos.
4.1 Recuentos, sumas y medias acumulados
Un contador registra cuántos valores cumplen una condición. Un acumulador combina valores en un resultado acumulado. Declara ambos antes del bucle para que cada pasada se base en el trabajo anterior.
Inicializa según la operación
Utiliza int count = 0; e incrementa el contador cuando un elemento cumpla la condición. Una suma empieza en 0 y utiliza sum += value;. Un producto empieza en 1, porque multiplicar un 0 inicial borraría todos los factores posteriores. Inicializar un total dentro del cuerpo lo reinicia en cada pasada.
Para un rango, el incremento del bucle puede seleccionar los valores: sumar los enteros pares de 2 a 100 con incrementos de 2 da 2550. También puedes colocar una condición dentro del bucle. Contar los números de 1 a 100 divisibles por 3 o por 5 da 47: los seis múltiplos de 15 deben contarse una sola vez.
Detén la entrada antes de sumarla
Un centinela es un valor especial de entrada que termina la lectura. No es un valor de datos normal:
int sum = 0;
int count = 0;
while (true) {
int number = Integer.valueOf(scanner.nextLine());
if (number == 0) {
break;
}
sum += number;
count++;
}
Para la entrada 12, 7, 5, 0, la suma pasa por 12, 19 y 24. El contador llega a 3. El 0 final activa el break antes de que cambie cualquiera de las dos variables. Contarlo crearía un cuarto elemento y daría una media incorrecta, aunque sumar cero deje la suma sin cambios.
Divide solo después de comprobar el recuento
if (count > 0) {
double average = (double) sum / count;
System.out.println(average);
} else {
System.out.println("No numbers entered");
}
El ejemplo imprime 8,0. Con operandos enteros, la división descarta la parte fraccionaria: 25 / 4 es 6. Convierte antes de dividir para obtener 6,25: (double) sum / count. Convertir explícitamente después, (double) (sum / count), solo convierte el resultado ya truncado en 6,0.
Si el centinela llega primero, el recuento es 0. La división entera entre cero lanza una ArithmeticException; una suma de cero en coma flotante dividida entre cero da NaN. La comprobación del recuento evita que una entrada vacía produzca una media sin sentido.
Sigue varios resultados en una pasada
Para las puntuaciones 55, 72, 90, 48 y 81, una nota de aprobación de 60 produce cinco puntuaciones y tres aprobados. Mantén un contador total para cada puntuación y un contador de aprobados dentro de la condición de aprobación. 100.0 * passed / total da 60,0 por ciento; 100.0 hace que la aritmética sea en coma flotante. Comprueba también que el total sea positivo antes de esta división.
El lugar donde se imprime cambia lo que se muestra. Las distancias de 5, 3 y 8 km dan sumas acumuladas de 5, 8 y 16 km cuando se imprimen dentro del bucle después de la suma. Imprimir después da solo los 16 km finales.
Elige un tipo suficientemente amplio para el total
El máximo de un int es 2 147 483 647. La suma de todos los enteros de 1 a 100 000 debería dar 5 000 050 000, pero un int se desborda y da 705 082 704 sin informar de un error. long sum = 0; almacena esta suma correctamente; el máximo de long es aproximadamente 9,2 × 10¹⁸. Ampliar después un resultado que ya se ha desbordado no puede recuperar el valor perdido.
Puntos clave
- Inicializa una suma o un contador en 0 y un producto en 1.
- Excluye el centinela tanto de la suma como del recuento.
- Convierte un operando antes de la división para conservar la fracción.
- Protege las medias y los porcentajes frente a una entrada vacía.
- Mantén la actualización de cada contador junto a la condición que cuenta.
- Utiliza un tipo suficientemente amplio antes de acumular un total grande.
4.2 Valores extremos, búsquedas y dígitos
Algunos bucles recuerdan un mejor valor; otros recuerdan si se ha producido una coincidencia. Elige el estado inicial de modo que refleje la situación real antes y después de cada pasada.
Conserva el mejor valor encontrado hasta el momento
Para seguir un máximo, sustitúyelo solo cuando el valor actual sea mayor: if (value > max) { max = value; }. Empezando por la primera lectura, las temperaturas 14, 19, 11, 23 y 17 °C dejan como máximos sucesivos 14, 19, 19, 23 y 23 °C. Para un mínimo se utiliza < en su lugar.
Empezar un máximo en 0 falla con datos exclusivamente negativos: -5, -2 y -9 dejarían incorrectamente 0 como resultado. Inicializa a partir de una lectura real o empieza en Integer.MIN_VALUE para un máximo de tipo int y en Integer.MAX_VALUE para un mínimo de tipo int. Indica que no hay resultado cuando no haya lecturas.
Para registrar una posición, actualízala en la misma rama que el valor. Un > estricto conserva el primer máximo en caso de empate; >= vuelve a sustituirlo y conserva el último.
Detente después de encontrar una coincidencia
int n = 1;
while (n * n <= 500) {
n++;
}
Con 22, el cuadrado es 484, por lo que se ejecuta otra pasada. Con 23, es 529 y la condición falla. El bucle ha encontrado el menor entero positivo cuyo cuadrado supera 500. Una búsqueda con límites puede, en cambio, comprobar cada candidato en un bucle for y salir con break al encontrar la primera coincidencia.
Para una pregunta sobre algún valor, inicia un indicador en falso y ponlo en verdadero al encontrar una coincidencia. Para una pregunta sobre todos los valores, empieza en verdadero y ponlo en falso al encontrar un contraejemplo. No reinicies ninguno de los indicadores en una rama else con valores posteriores: por ejemplo, una lectura posterior que no coincida no borra una lectura negativa anterior.
Comprueba si hay un divisor
Un número primo es al menos 2 y no tiene ningún divisor desde 2 hasta uno menos que él mismo. Para un entero positivo pequeño, una comprobación más corta prueba divisores solo hasta su raíz cuadrada:
int n = 91;
boolean isPrime = n >= 2;
for (int d = 2; d * d <= n; d++) {
if (n % d == 0) {
isPrime = false;
break;
}
}
Los dos factores de un par no pueden superar ambos la raíz cuadrada. Para 91, el divisor 7 da un resto de cero y cambia el indicador a falso. Para 97, ningún divisor de 2 a 9 lo divide, por lo que el indicador permanece verdadero. Los valores inferiores a 2 empiezan con un indicador falso. Para valores int positivos grandes, utiliza d <= n / d para evitar el desbordamiento en d * d.
Elimina un dígito decimal por pasada
Para un entero no negativo, % 10 extrae el último dígito y la división entera / 10 lo elimina:
int n = 4072;
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
Los dígitos son 2, 7, 0 y 4, y dan 13. La variable de trabajo n termina en 0. Para invertir los dígitos, actualiza reversed = reversed * 10 + n % 10; antes de eliminar el dígito; 1234 se convierte en 4321 cuando el resultado cabe en el tipo elegido.
Para contar dígitos, el cero necesita una pasada aunque n > 0 empiece siendo falso. Utiliza un do-while que incremente el contador y divida n entre 10. Cuenta un dígito para 0 y el número habitual para valores positivos.
Puntos clave
- Inicializa un valor extremo a partir de datos reales o de un límite adecuado del tipo.
- Actualiza la posición de un valor extremo junto con su valor.
- Mantén verdadero un indicador de búsqueda después de una coincidencia de «alguno», o falso después de un contraejemplo de «todos».
- Una prueba de primalidad no necesita divisores superiores a la raíz cuadrada.
- Para enteros no negativos,
% 10extrae un dígito y/ 10lo elimina. - Contar los dígitos de cero requiere una primera pasada obligatoria.
4.3 Trabajo anidado, seguimiento y casos de prueba
Los bucles anidados repiten una repetición completa por cada pasada externa. Son útiles para filas, columnas, tablas y formas. El bucle interno debe comenzar de nuevo cada vez que el bucle externo llega a él.
Imprime una fila y después termina la línea
for (int row = 1; row <= 3; row++) {
for (int col = 1; col <= 5; col++) {
System.out.print(row * col + "\t");
}
System.out.println();
}
La primera fila contiene 1, 2, 3, 4, 5; la segunda contiene 2, 4, 6, 8, 10; la tercera contiene 3, 6, 9, 12, 15. El print interno crea columnas en una línea; el println después del bucle interno termina esa fila. Mover println dentro del bucle interno coloca cada producto en su propia línea.
Con recuentos fijos, multiplica las pasadas externas por las internas. Tres pasadas externas y cuatro internas ejecutan el cuerpo interno 12 veces. La tabla anterior imprime tres por cinco, es decir, 15 productos.
Deja que cambie el tamaño de la fila
for (int row = 1; row <= 4; row++) {
for (int col = 1; col <= row; col++) {
System.out.print("*");
}
System.out.println();
}
El límite interno depende ahora de la fila. Sus recuentos son 1, 2, 3 y 4, por lo que el triángulo contiene 10 asteriscos. Una sola multiplicación de recuentos fijos sería incorrecta porque el bucle interno no se ejecuta el mismo número de veces en cada fila.
Utiliza nombres distintos para contadores de bucle cuyos ámbitos se solapan. Declarar otro int i dentro de un bucle donde i ya está en el ámbito hace que la compilación falle. Para un bucle while interno, inicializa su contador al comienzo de cada pasada externa. Inicializarlo solo antes del bucle externo hace que quede por encima del límite después de la primera fila.
Sigue los valores en un punto constante
Para un bucle de 1 a 4, resta los valores impares de un total que empieza en 0 y suma los pares:
| Valor procesado | Acción | Total después de la pasada |
|---|---|---|
| 1 | Restar 1 | -1 |
| 2 | Sumar 2 | 1 |
| 3 | Restar 3 | -2 |
| 4 | Sumar 4 | 2 |
Registra si una fila describe el comienzo o el final de una pasada. Incluye la condición final que falla al comprobar la terminación. Un seguimiento que mezcle valores anteriores y posteriores a la actualización puede hacer que un bucle correcto parezca incorrecto.
Coloca separadores entre elementos
Cinco números necesitan cuatro comas. Imprime un separador antes de cada elemento salvo el primero:
for (int i = 1; i <= 5; i++) {
if (i > 1) {
System.out.print(", ");
}
System.out.print(i);
}
La salida es «1, 2, 3, 4, 5», sin coma inicial ni final. Este es un problema de los postes y los intervalos: el número de espacios entre elementos difiere del número de elementos.
Prueba casos que revelen errores
Prueba cero pasadas, una pasada y los valores en cada límite y junto a él. Para bucles de entrada, prueba primero el centinela. Para bucles anidados, comprueba si la segunda fila se reinicia correctamente. Las impresiones temporales de las variables del bucle revelan el progreso real. Si un programa se bloquea, revisa cada ruta para buscar una actualización o una salida y detenlo con Ctrl+C en una terminal o con el botón de parada del entorno de desarrollo.
Puntos clave
- El bucle interno se completa en cada pasada externa.
- Multiplica los recuentos de pasadas solo cuando ambos sean fijos.
- Reinicia el contador de un while interno en cada pasada externa.
- Coloca el salto de línea de una fila después de su bucle interno.
- Utiliza un punto constante de cada pasada para las filas de la tabla de seguimiento.
- Prueba cero pasadas, una pasada y ambos lados de un límite.
- Los separadores van entre elementos, por lo que su recuento es uno menor.
Ejemplos de Condiciones y bucles en Java
1Convierte una regla del programa en una condición
12 pasos
- 1IntroducciónEmpieza con una regla sobre los datos
Una condición responde a una pregunta de verdadero o falso sobre los datos actuales. Empieza con comparaciones sencillas y después combínalas en una regla que acepte exactamente los valores deseados.
Comprobaremos un rango de temperaturas, compararemos texto y protegeremos una división entera. En cada paso, distingue lo que significa la condición del orden en que Java la evalúa.
- 2ExplicaciónDa nombre a una comparación
Una comparación produce un
boolean, que puede almacenarse para utilizarlo después.int age = 17; boolean isAdult = age >= 18;Aquí
isAdultalmacenafalse. La expresiónif (isAdult)comprueba después ese valor directamente. Un entero por sí solo no puede servir como condición:if (age)falla porque Java requiere un booleano, no un número usado como valor de verdad. - 3EjemploLee el operador con precisión
Con
a = 7yb = 10,a < bes verdadero ya >= bes falso. Las comparacionesa != bya == 7son verdaderas.La diferencia entre
=y==importa: la asignación cambia una variable, mientras que la comparación plantea una pregunta. Para un booleano,if (done = true)compila, pero sobrescribe el indicador antes de comprobarlo. Utilizaif (done)para comprobar el valor existente. - 4ConsejoCompara los caracteres de la entrada
Una cadena no nula como
commandtiene contenido de texto y una identidad de objeto.command.equals("quit")comprueba los caracteres;command == "quit"comprueba la identidad.Utiliza
equalsIgnoreCasesolo cuando deban aceptarse las diferencias entre mayúsculas y minúsculas. Por ejemplo, «Quit» y «quit» coinciden con ese método, pero son distintos conequals. Negar una coincidencia exacta da!command.equals("quit"). - 5EjemploComprueba una diferencia decimal
double sum = 0.1 + 0.2; boolean close = Math.abs(sum - 0.3) < 1e-9;La suma se almacena como
0.30000000000000004. La igualdad exacta con0.3es falsa, pero la diferencia absoluta está por debajo de esta tolerancia, lo que hace queclosesea verdadero. La comprobación de tolerancia acepta una pequeña diferencia; no cambia ninguno de los valores almacenados ni hace que sean exactamente iguales. - 6DesafíoComprueba un número impar negativo
Un programa utiliza
n % 2 == 1para detectar enteros impares. ¿Qué deja sin detectar cuandones -11 y cómo puede corregirse la comprobación?---reveal---
-11 % 2es-1, por lo que la comprobación es falsa aunque -11 sea impar. Utilizan % 2 != 0: la divisibilidad por 2 tiene un resto de cero, y tanto los restos positivos como los negativos distintos de cero identifican enteros impares. - 7ExplicaciónExige ambos límites
Para aceptar temperaturas de 18 a 24 °C, exige ambas comparaciones:
temp >= 18 && temp <= 24.Con 21, ambas son verdaderas. Con 17, la primera es falsa; con 25, la segunda es falsa. Utilizar
||entre estos límites interiores aceptaría los tres valores, porque cada uno cumple al menos una de las dos comprobaciones. Cada operando debe ser una expresión booleana completa. - 8Idea claveInvierte todo el rango
Estar fuera del mismo rango significa
temp < 18 || temp > 24. Basta con que no se cumpla uno de los límites para estar fuera.Esta es la ley de De Morgan en acción:
!(p && q)equivale a!p || !q. Negar ambas partes también cambia el operador que las une. La ley complementaria es!(p || q)equivalente a!p && !q; mantener el operador anterior cambiaría las entradas que se aceptan. - 9EjemploColoca una protección antes de la división
int total = 36; int count = 0; boolean large = count != 0 && total / count > 10;La primera comparación falsa determina el resultado, por lo que
&&omite la división. Esto es la evaluación en cortocircuito. Invertir los operandos dividiría entre cero antes de comprobar count y lanzaría unaArithmeticException. Con||, un operando izquierdo verdadero omite igualmente el derecho. - 10DesafíoDistingue la agrupación del orden de lectura
Con
a = true,b = falseyc = false, ¿dana || b && cy(a || b) && cel mismo resultado? Explica la agrupación.---reveal---
No. La primera se agrupa como
a || (b && c)porque&&tiene mayor precedencia, por lo que es verdadera. La segunda requiere el resultado dea || by tambiénc; comoces falso, ese resultado es falso. - 11DesafíoCombina un límite y una excepción
Se acepta una carga si está entre 6 y 14 kg o si hay una anulación activa, pero también debe realizarse de forma segura un cálculo entero
100 / count > 5. Escribe la condición de modo que un count de 0 no pueda llegar a la división.---reveal---
count != 0 && (load >= 6 && load <= 14 || override) && 100 / count > 5La primera protección rechaza el cero. La elección agrupada acepta el rango o la anulación; solo una ruta que supere las comprobaciones llega a la división.
- 12RepasoComprueba una condición desde ambos lados
Antes de utilizar una condición, prueba una entrada que deba aceptarse y otra que deba rechazarse. Para intervalos, comprueba también los extremos.
Lee los paréntesis y la precedencia para identificar la agrupación y después sigue la evaluación en cortocircuito de izquierda a derecha. Esto detecta tanto una regla de aceptación incorrecta como un cálculo que se ejecuta antes de su protección.
2Elige una ruta y produce un resultado
14 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónSigue la ruta a la que llega Java
- 2EjemploEjecuta exactamente una rama
- 3ExplicaciónConserva el resultado después de la decisión
- 4DesafíoEncuentra una impresión incondicional
- 5ConsejoHaz explícita la elección interna
- 6EjemploRecorre los umbrales en el orden adecuado
- 7ConexiónSepara las acciones independientes
- 8DesafíoCorrige un extremo omitido
- 9ExplicaciónElige según un valor exacto
- 10EjemploAsigna el valor elegido
- 11ExplicaciónProporciona su valor a un bloque
- 12DesafíoSigue la continuación entre casos con dos puntos
- 13DesafíoElige una estructura para una regla combinada
- 14RepasoExamina los límites de la decisión
3Sigue un bucle desde su primera pasada hasta su salida
18 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónObserva cómo cambia el estado
- 2ExplicaciónComprueba antes de entrar
- 3EjemploSigue un producto que cambia
- 4DesafíoEvita saltarte un valor de parada
- 5ExplicaciónEjecuta una vez antes de decidir
- 6EjemploLee una valoración antes de comprobarla
- 7DesafíoPredice un extremo aceptado
- 8ConexiónLleva el conteo a la cabecera
- 9EjemploCuenta con incrementos mayores que uno
- 10DesafíoConserva el extremo deseado
- 11ConsejoComprueba si hay un cuerpo vacío
- 12EjemploDetente en la primera coincidencia
- 13ExplicaciónOmite el resto de una pasada
- 14DesafíoEncuentra la actualización omitida
- 15ExplicaciónDa un nombre de salida a un bucle externo
- 16ConexiónDistingue las salidas de switch y de bucle
- 17DesafíoCombina una omisión y una salida anticipada
- 18RepasoSigue el siguiente destino
4Construye resultados que describan todos los datos procesados
19 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónDecide qué debe conservarse entre pasadas
- 2ExplicaciónSepara un recuento de una suma
- 3EjemploLee y rechaza el centinela
- 4EjemploSigue el estado durante la entrada
- 5ExplicaciónConserva la parte fraccionaria de la media
- 6DesafíoCalcula la media solo de las lecturas aceptadas
- 7ConsejoUtiliza un tipo amplio a tiempo
- 8EjemploConserva la mejor lectura
- 9DesafíoRegistra dónde se produce un empate
- 10Idea claveDeja que un indicador recuerde una coincidencia
- 11ExplicaciónBusca un divisor
- 12EjemploExtrae dígitos en un orden fijo
- 13DesafíoMantén registrada una lectura negativa
- 14ExplicaciónCompleta cada fila antes de avanzar
- 15EjemploCuenta filas de tamaño variable
- 16DesafíoCorrige el separador en el primer elemento
- 17ConsejoElige filas de seguimiento reveladoras
- 18DesafíoCombina un límite cambiante con una selección
- 19RepasoComprueba el significado de cada resultado
Ejercicios de Condiciones y bucles en Java
Set 1: Interpreta condiciones y elige una ruta10 Preguntas de Práctica
Pregunta 1 de 10
-13 % 2 != 0?Mostrar respuestaOcultar respuesta
Pregunta 2 de 10
String command no nulo contiene texto leído de la entrada. ¿Qué expresión comprueba si su contenido es exactamente «pause»?Mostrar respuestaOcultar respuesta
Pregunta 3 de 10
Mostrar respuestaOcultar respuesta
Pregunta 4 de 10
¿Qué imprime esto?
boolean ready = true;
boolean locked = false;
boolean expired = false;
System.out.println(ready || locked && expired);
Mostrar respuestaOcultar respuesta
Pregunta 5 de 10
¿Qué imprime este código?
int stock = 0;
if (stock > 0) {
System.out.print("available ");
} else {
System.out.print("empty ");
}
System.out.print("checked");
Mostrar respuestaOcultar respuesta
Pregunta 6 de 10
¿Qué se imprime?
int load = 74;
if (load >= 50) {
System.out.print("medium");
} else if (load >= 70) {
System.out.print("high");
} else {
System.out.print("low");
}
Mostrar respuestaOcultar respuesta
Pregunta 7 de 10
¿Qué valor se almacena en mode?
String command = "RUN";
int mode = switch (command) {
case "run" -> 1;
case "wait" -> 2;
default -> 3;
};
Mostrar respuestaOcultar respuesta
Pregunta 8 de 10
int sum = 15; y int count = 0;, ¿qué ocurre al evaluar count == 0 || sum / count > 4?Mostrar respuestaOcultar respuesta
Pregunta 9 de 10
¿Por qué este código no compila?
int value = 8;
String label;
if (value > 5) {
label = "large";
}
System.out.println(label);
Mostrar respuestaOcultar respuesta
Pregunta 10 de 10
member && !blocked || guest && codeValid es verdadero. ¿Qué condición rechaza exactamente las entradas que permitiría?Mostrar respuestaOcultar respuesta
Set 2: Sigue las comprobaciones, actualizaciones y salidas de bucles10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
¿Cuántas veces se ejecuta el cuerpo?
int n = 12;
while (n < 8) {
n++;
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
¿Qué se imprime?
int level = 9;
do {
level -= 2;
} while (level > 8);
System.out.println(level);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
¿Cuántas ejecuciones del cuerpo se producen?
for (int k = 2; k <= 17; k += 4) {
System.out.println(k);
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
¿Qué se imprime, ignorando el espacio final?
for (int k = 2; k <= 7; k++) {
if (k % 2 == 0) {
continue;
}
System.out.print(k + " ");
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
¿Cuáles son los valores de amount y steps después de este bucle?
int amount = 3;
int steps = 0;
while (amount < 40) {
amount *= 2;
steps++;
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
¿Cuál es el valor final de total?
int total = 0;
for (int k = 1; k <= 8; k++) {
if (k % 3 == 0) {
continue;
}
total += k;
if (total > 12) {
break;
}
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
int index. ¿Dónde puede el código leer esa variable?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
¿Qué se imprime?
int hits = 0;
outer:
for (int row = 1; row <= 4; row++) {
for (int col = 1; col <= 4; col++) {
if (row + col == 5) {
break outer;
}
hits++;
}
}
System.out.println(hits);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
¿Por qué nunca termina este bucle?
int n = 1;
while (n != 12) {
n += 2;
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 3: Calcula resultados a partir de entradas repetidas10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
int sum = 17; e int count = 4;, ¿qué resultado da (double) (sum / count)?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
max en 0 puede dar una respuesta incorrecta?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
¿Qué se imprime?
int n = 6205;
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
System.out.println(sum);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
¿Cuántos asteriscos se imprimen en total?
for (int row = 2; row <= 5; row++) {
for (int col = 1; col < row; col++) {
if (col == 2) {
continue;
}
System.out.print("*");
}
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
¿Cuáles son los valores de best y position después?
int best = Integer.MIN_VALUE;
int position = 0;
for (int day = 1; day <= 5; day++) {
int value = day % 3 - 4;
if (value >= best) {
best = value;
position = day;
}
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
¿Cuál es la salida?
for (int k = 3; k <= 5; k++) {
if (k > 3) {
System.out.print(", ");
}
System.out.print(k);
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
¿Qué imprime este código?
boolean allPositive = true;
for (int k = 1; k <= 4; k++) {
int value = k - 2;
if (value <= 0) {
allPositive = false;
} else {
allPositive = true;
}
}
System.out.println(allPositive);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 4: Combina decisiones con patrones de bucles10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
¿Qué se imprime?
int result = 0;
switch (2) {
case 1:
result += 2;
case 2:
result += 3;
case 3:
result += 5;
break;
default:
result = -1;
}
System.out.println(result);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
¿Cuál es el valor de total después del bucle?
int total = 0;
for (int k = 1; k <= 5; k++) {
switch (k % 3) {
case 0:
break;
default:
total += k;
}
total++;
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
¿Cuál es el total final?
int total = 0;
for (int n = 1; n <= 9; n++) {
if (n % 2 == 0) {
total += 2;
} else if (n % 3 == 0) {
total += 3;
} else {
total--;
}
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
do { ... } while (value < 10 || value > 14);. ¿Cuántas entradas consume?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
¿Qué se imprime?
int n = 58;
int result = 0;
do {
int digit = n % 10;
if (digit % 2 == 0) {
result = result * 10 + digit;
}
n /= 10;
} while (n > 0);
System.out.println(result);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
Math.abs((0.1 + 0.2) - 0.3) < 1e-9 puede ser verdadero mientras que (0.1 + 0.2) == 0.3 es falso?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
(double) sum / count. ¿Cuál es el resultado y qué corrección se necesita?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
¿Qué imprime este código?
for (int n = 4; n > 0; n--);
{
System.out.print("done");
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 5: Encuentra errores y predice comportamientos combinados10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
!(false || true)?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
¿Qué se imprime?
int a = -2;
int b = 5;
if (a > 0)
if (b > 0)
System.out.print("both");
else
System.out.print("one");
System.out.print("end");
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
¿Qué valor se asigna?
int level = 3;
int result = switch (level) {
case 1, 2 -> 4;
case 3 -> {
int base = level * 2;
yield base + 1;
}
default -> 0;
};
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
¿Cuál es el count final?
int count = 0;
outer:
for (int row = 1; row <= 3; row++) {
for (int col = 1; col <= 3; col++) {
if (row == col) {
continue outer;
}
count++;
}
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
n = 143, un bucle de prueba de primalidad empieza en el divisor 2 y continúa mientras se cumpla d * d <= n, ejecutando break cuando el resto es cero. ¿En qué divisor ejecuta break por primera vez?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
¿Cuál es el valor de count al final?
int count = 0;
int col = 1;
for (int row = 1; row <= 3; row++) {
while (col <= row) {
count++;
col++;
}
}
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
(double) sum / count y qué corrección se necesita?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
¿Qué recuento de dígitos produce esto para n = 0?
int n = 0;
int digits = 0;
do {
digits++;
n /= 10;
} while (n > 0);
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
score < 0 || score > 40, después asigna «high» a score >= 30, «middle» a score >= 18 y «low» al resto. ¿Qué etiquetas reciben las puntuaciones 40, 41 y 18, en ese orden?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
¿Te atascas con una pregunta tuya? Ayuda con Tareas
Términos Clave
Á
Ámbito (alcance)
A
Actualización
i += 4 mueve el contador de 2 a 6 después de que termina el primer cuerpo del bucle for.Acumulador
B
Bloque
Bucle anidado
Bucle con condición al final
Bucle do-while
Bucle externo
Bucle for
Bucle infinito
i <= 5 produce un bucle infinito, salvo que otra ruta permita salir.Bucle interno
Bucle while (ciclo while)
Búsqueda
C
Cadena de condiciones else-if
Caso extremo
Centinela
Condición de continuación
Conjunción lógica
&&.Contador
Continuación entre casos
Contraejemplo
D
Desbordamiento
Disyunción exclusiva
^.Disyunción lógica
||.División entera
17 / 4, por lo que un cálculo de media convierte primero un operando.E
else ambiguo
Error de una unidad
< 12 pero debe incluir 12.Etiqueta case
Evaluación en cortocircuito
&& o || cuando el operando izquierdo ya determina todo el resultado.count != 0 && sum / count > 5 sea segura cuando ambas variables son int.Exhaustividad
Expresión switch
Extracción de dígitos
% 10, listo para utilizarlo antes de que la división lo elimine.I
Indicador booleano (bandera)
Inicialización
Iteración
L
Leyes de De Morgan
M
Máximo
Mínimo
N
Negación
!, convirtiendo verdadero en falso y falso en verdadero sin cambiar los datos subyacentes.!command.equals("stop") es verdadera mientras el texto introducido sea distinto de «stop».Número primo
O
Operador condicional
?: selecciona uno de dos valores de expresión según una condición booleana, lo que permite una breve elección entre dos valores.label «even» u «odd» según una comprobación del resto.Operador de asignación
= almacena un valor en una variable; la expresión resultante tiene ese valor asignado, no un resultado de comparación.if (done = true) cambia el indicador antes de que se ejecute la rama.Operador de comparación
<= incluye una puntuación igual al límite superior de un rango permitido.Operador de igualdad
== compara valores primitivos, pero con referencias a objetos como las cadenas comprueba si los objetos son idénticos.3 == 3.0 porque la conversión numérica hace que sus valores sean iguales.P
Precedencia de operadores
a || b && c signifique a || (b && c), aunque la disyunción aparezca primero.Problema de los postes y los intervalos
Prueba de valores límite
R
Rama
Resto (residuo)
% después de una división entera; un resto cero identifica un valor divisible por el divisor.-13 % 2 es -1, por lo que comprobar si el resto es distinto de cero reconoce este entero impar.S
Salida anticipada
Selector
command dirige el texto «wait» a un caso con esa etiqueta de cadena exacta.Sentencia break
Sentencia break con etiqueta
Sentencia continue
Sentencia continue con etiqueta
Sentencia yield
Suma acumulada
T
Tabla de seguimiento
Tolerancia
1e-9 acepta la pequeña diferencia entre 0.1 + 0.2 y 0.3 en este cálculo.U
Umbral
score >= 30 incluye 30, mientras que score > 30 deja fuera esa puntuación exacta.V
Validación de entrada
Valor booleano
true o false; las comparaciones lo producen y las condiciones de Java requieren una expresión de este tipo.isFull pasa a ser verdadero cuando un recipiente alcanza su capacidad.Variable de bucle
- 1Primeros programas en Java
- 2Condiciones y bucles en Java
- 3Métodos en Java
- 4Listas, arreglos y cadenas en Java
- 5Clases y objetos en Java
- 6Objetos y referencias en Java
- 7HashMap y colecciones en Java
- 8Herencia, interfaces y polimorfismo en Java
- 9Excepciones y archivos en Java
- 10Paquetes en Java
- 11Genéricos y expresiones lambda en Java
Sobre esta unidad
Crea tus propios Materiales de Estudio
Convierte tus notas, diapositivas y documentos en Guías de Estudio, Preguntas de Práctica, Flashcards y 6 herramientas más.