Variables en Java — ejercicios para dominar tipos, casting y Strings
En la práctica ya provocamos los tres sustos clásicos de las variables en Java. Ahora toca resolver por tu cuenta — pero con un giro: los ejercicios de aquí no van a poner el foco exactamente en lo mismo que la práctica. La división entera, el casting y el == aparecen, pero como herramientas para resolver algo, no como el protagonista. Eso es lo que pasa en los exámenes reales.
Tres niveles, tres contextos distintos. Intenta resolverlos antes de mirar la solución — aunque sea 10 minutos peleando con el compilador. Ese rato es donde ocurre el aprendizaje de verdad.
Variables en Java ejercicios — Nivel básico
Ejercicio 1 — Calculadora de IMC
Escribe un programa que pida el peso en kg y la altura en metros, calcule el Índice de Masa Corporal y muestre el resultado con su clasificación. Incluye también el peso ideal para esa altura.
El IMC se calcula así: IMC = peso / (altura × altura)
Salida esperada con 70 kg y 1.75 m:
=== CALCULADORA DE IMC === Peso (kg): 70 Altura (m): 1.75 --- Resultado --- IMC: 22,86 Clasificación: Normopeso Peso ideal: entre 56,7 kg y 80,1 kg Rango saludable: 18,5 - 24,9 Estado: ✓ Tu peso está dentro del rango saludable
Clasificaciones:
IMC < 18.5 → Bajo peso IMC entre 18.5-24.9 → Normopeso IMC entre 25-29.9 → Sobrepeso IMC >= 30 → Obesidad
Peso ideal: el rango corresponde a IMC 18.5 y 24.9 para esa altura.
💡 Pistas:
altura * altura— no existealtura^2en Java, eso es XOR bit a bit. Para potencias usaMath.pow(altura, 2)o simplemente multiplica- El peso ideal mínimo es
18.5 * altura * alturay el máximo24.9 * altura * altura - Usa
if/else ifen cadena para la clasificación — noswitch, porque estás comparando rangos dedouble
Variables en Java ejercicios — Nivel intermedio
Ejercicio 2 — Conversor de tiempo
Escribe un programa que pida un número de segundos totales y lo descomponga en días, horas, minutos y segundos. Muestra también el porcentaje que representa dentro de un día completo.
Salida esperada con 90061 segundos:
=== CONVERSOR DE TIEMPO === Segundos totales: 90061 --- Desglose --- 1 día, 1 hora, 1 minuto y 1 segundo --- En detalle --- Días: 1 (86400 segundos) Horas: 1 (3600 segundos) Minutos: 1 (60 segundos) Segundos: 1 --- Porcentaje del día --- 90061 segundos = 104,24% de un día completo (más de un día completo)
💡 Pistas:
- Este ejercicio es todo división entera y módulo — no necesitas ningún
doublehasta el porcentaje final - El orden importa: primero calcula días (
segundos / 86400), luego el resto (% 86400), luego horas de ese resto, y así - Para el porcentaje necesitas el cast:
(double) segundos / 86400 * 100 - Ojo con el texto: «1 hora» vs «2 horas» — singular y plural cambian. Usa el operador ternario
Variables en Java ejercicios — Desafío final
Ejercicio 3 — Tienda con productos
Escribe un programa completo que gestione la información de tres productos de una tienda. Para cada producto pide nombre, precio base y unidades en stock. El programa genera un informe con los precios con IVA (21%), el valor total del inventario y el producto más caro.
Salida esperada:
=== GESTIÓN DE TIENDA === --- Producto 1 --- Nombre: Portátil Precio base (€): 899.99 Stock: 5 --- Producto 2 --- Nombre: Ratón Precio base (€): 29.99 Stock: 23 --- Producto 3 --- Nombre: Teclado Precio base (€): 79.99 Stock: 12 ╔═══════════════════════════════════════════════╗ ║ INFORME DE INVENTARIO ║ ╠═══════════════╦═══════════╦════════╦══════════╣ ║ Producto ║ Base ║ +IVA ║ Stock ║ ╠═══════════════╬═══════════╬════════╬══════════╣ ║ Portátil ║ 899,99 € ║1088,99€║ 5 ║ ║ Ratón ║ 29,99 € ║ 36,29€║ 23 ║ ║ Teclado ║ 79,99 € ║ 96,79€║ 12 ║ ╠═══════════════╩═══════════╩════════╩══════════╣ ║ Valor total inventario: 6.384,88 € ║ ║ Producto más caro (sin IVA): Portátil ║ ║ Producto más barato (sin IVA): Ratón ║ ╚═══════════════════════════════════════════════╝
El valor total del inventario es la suma de precio × stock para cada producto.
💡 Pistas:
- Declara arrays de tres posiciones:
String[] nombres = new String[3],double[] precios = new double[3],int[] stocks = new int[3] - Para encontrar el más caro: empieza asumiendo que el primero es el más caro y recorre los demás comparando
- El valor del inventario de cada producto es
precios[i] * stocks[i]— mucho ojo con la división entera aquí si mezclas tipos - El
sc.nextLine()de limpieza va después desc.nextDouble()ysc.nextInt()— ya lo conoces
¿Qué falla aquí?
Antes de ver las soluciones, estos son los errores más frecuentes en este tipo de ejercicios. ¿Encuentras el problema en cada uno?
Error 1
int segundos = 90061;
double porcentaje = segundos / 86400 * 100;
System.out.printf("%.2f%%%n", porcentaje);
// Muestra: 100,00% en lugar de 104,24%
¿Lo ves? segundos / 86400 es división entera — da 1. Luego 1 * 100 = 100.0. El cast tiene que ir antes:
double porcentaje = (double) segundos / 86400 * 100; // Ahora sí: 104,24%
Error 2
Scanner sc = new Scanner(System.in);
System.out.print("Nombre: ");
String nombre = sc.nextLine();
System.out.print("Precio: ");
double precio = sc.nextDouble();
System.out.print("Categoría: ");
String categoria = sc.nextLine(); // ← lee cadena vacía
Falta el sc.nextLine() de limpieza después del nextDouble(). La solución:
double precio = sc.nextDouble(); sc.nextLine(); // ← consume el \n sobrante String categoria = sc.nextLine(); // ahora espera al usuario
Error 3
String cat = sc.nextLine().trim().toLowerCase();
if (cat == "electronica") {
System.out.println("Categoría válida");
}
// Nunca entra en el if aunque escribas "electronica"
== compara referencias de memoria, no contenido. Siempre:
if (cat.equals("electronica")) { // ← correcto
Soluciones comentadas
Solución Ejercicio 1
import java.util.Scanner;
public class CalculadoraIMC {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== CALCULADORA DE IMC ===");
System.out.println();
System.out.print("Peso (kg): ");
double peso = sc.nextDouble();
System.out.print("Altura (m): ");
double altura = sc.nextDouble();
// Calculamos el IMC — ojo: no existe ^ en Java para potencias
// altura * altura es lo más directo y claro para este caso
// Math.pow(altura, 2) también funciona pero es excesivo aquí
double imc = peso / (altura * altura);
// Calculamos el rango de peso ideal para esta altura
// multiplicamos por el IMC límite, no al revés
double pesoMinimo = 18.5 * (altura * altura);
double pesoMaximo = 24.9 * (altura * altura);
// Clasificación — usamos if/else if porque comparamos rangos de double
// switch no sirve aquí: solo funciona con valores exactos, no rangos
String clasificacion;
if (imc < 18.5) {
clasificacion = "Bajo peso";
} else if (imc < 25.0) {
clasificacion = "Normopeso"; // entre 18.5 y 24.9
} else if (imc < 30.0) {
clasificacion = "Sobrepeso"; // entre 25 y 29.9
} else {
clasificacion = "Obesidad"; // 30 o más
}
// Determinamos si está en rango saludable — boolean limpio
boolean saludable = (imc >= 18.5 && imc < 25.0);
System.out.println();
System.out.println("--- Resultado ---");
// %.2f para mostrar dos decimales — el IMC no necesita más precisión
System.out.printf("IMC: %.2f%n", imc);
System.out.printf("Clasificación: %s%n", clasificacion);
System.out.printf("Peso ideal: entre %.1f kg y %.1f kg%n",
pesoMinimo, pesoMaximo);
System.out.printf("Rango saludable: 18,5 - 24,9%n");
System.out.println();
// El operador ternario aquí es más compacto que un if/else
// si la condición es simple, el ternario lo hace más legible
System.out.printf("Estado: %s%n",
saludable
? "✓ Tu peso está dentro del rango saludable"
: "⚠ Tu peso está fuera del rango saludable");
sc.close();
}
}
Solución Ejercicio 2
import java.util.Scanner;
public class ConversorTiempo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== CONVERSOR DE TIEMPO ===");
System.out.println();
System.out.print("Segundos totales: ");
int totalSegundos = sc.nextInt();
// Todo esto es división entera y módulo — sin doubles hasta el final
// El orden importa: primero los valores más grandes
// ¿Cuántos días completos caben?
int dias = totalSegundos / 86400; // 86400 = 60*60*24
int resto = totalSegundos % 86400; // lo que sobra tras quitar los días
// De lo que sobra, ¿cuántas horas completas?
int horas = resto / 3600; // 3600 = 60*60
resto = resto % 3600; // reutilizamos la variable resto
// De lo que queda, ¿cuántos minutos completos?
int minutos = resto / 60;
int segundos = resto % 60; // lo que sobra son segundos
System.out.println();
System.out.println("--- Desglose ---");
// Singular/plural con ternario — pequeño detalle que marca la diferencia
System.out.printf("%d %s, %d %s, %d %s y %d %s%n",
dias, (dias == 1 ? "día" : "días"),
horas, (horas == 1 ? "hora" : "horas"),
minutos, (minutos == 1 ? "minuto" : "minutos"),
segundos,(segundos == 1? "segundo": "segundos"));
System.out.println();
System.out.println("--- En detalle ---");
System.out.printf("Días: %-4d (86400 segundos)%n", dias);
System.out.printf("Horas: %-4d (3600 segundos)%n", horas);
System.out.printf("Minutos: %-4d (60 segundos)%n", minutos);
System.out.printf("Segundos: %d%n", segundos);
System.out.println();
System.out.println("--- Porcentaje del día ---");
// Aquí sí necesitamos double — y el cast va ANTES de dividir
// Si escribiéramos totalSegundos / 86400 * 100, la división entera
// truncaría el resultado antes de que el double entre en juego
double porcentaje = (double) totalSegundos / 86400 * 100;
System.out.printf("%d segundos = %.2f%% de un día completo%n",
totalSegundos, porcentaje);
// Mensaje adicional según el resultado
if (porcentaje > 100) {
System.out.println("(más de un día completo)");
} else if (porcentaje == 100) {
System.out.println("(exactamente un día completo)");
} else {
System.out.printf("(faltan %.2f%% para completar el día)%n",
100 - porcentaje);
}
sc.close();
}
}
Solución Ejercicio 3
import java.util.Scanner;
public class GestionTienda {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("=== GESTIÓN DE TIENDA ===");
System.out.println();
// Arrays para los tres productos — mismo índice = mismo producto
// Declaramos el tamaño fijo porque sabemos que son 3 productos
int numProductos = 3;
String[] nombres = new String[numProductos];
double[] precios = new double[numProductos];
int[] stocks = new int[numProductos];
// Recogemos los datos de cada producto con un bucle
// i va de 0 a 2 — los arrays en Java empiezan en 0, no en 1
for (int i = 0; i < numProductos; i++) {
System.out.printf("--- Producto %d ---%n", i + 1); // mostramos 1,2,3 al usuario
System.out.print("Nombre: ");
nombres[i] = sc.nextLine();
System.out.print("Precio base (€): ");
precios[i] = sc.nextDouble();
sc.nextLine(); // limpiamos el \n — ya sabes por qué
System.out.print("Stock: ");
stocks[i] = sc.nextInt();
sc.nextLine(); // otro \n sobrante
System.out.println();
}
// Calculamos el IVA y el valor de inventario de cada producto
double IVA = 0.21;
double[] preciosConIVA = new double[numProductos];
double[] valorInventario = new double[numProductos];
double totalInventario = 0;
for (int i = 0; i < numProductos; i++) {
preciosConIVA[i] = precios[i] * (1 + IVA);
// stocks[i] es int, precios[i] es double
// la multiplicación int*double da double automáticamente — widening
valorInventario[i] = precios[i] * stocks[i];
totalInventario += valorInventario[i];
}
// Buscamos el más caro y el más barato
// Estrategia: empezamos asumiendo que el primero es el extremo
// y recorremos los demás para ver si hay alguno mayor/menor
int indiceMasCaro = 0;
int indiceMasBarato = 0;
for (int i = 1; i < numProductos; i++) {
if (precios[i] > precios[indiceMasCaro]) {
indiceMasCaro = i; // encontramos uno más caro
}
if (precios[i] < precios[indiceMasBarato]) {
indiceMasBarato = i; // encontramos uno más barato
}
}
// Mostramos el informe formateado
System.out.println("╔═══════════════════════════════════════════════╗");
System.out.println("║ INFORME DE INVENTARIO ║");
System.out.println("╠═══════════════╦═══════════╦════════╦══════════╣");
System.out.println("║ Producto ║ Base ║ +IVA ║ Stock ║");
System.out.println("╠═══════════════╬═══════════╬════════╬══════════╣");
for (int i = 0; i < numProductos; i++) {
// %-13s alinea a la izquierda con 13 chars — los nombres quedan alineados
System.out.printf("║ %-13s ║ %7.2f € ║%6.2f€║ %8d ║%n",
nombres[i], precios[i], preciosConIVA[i], stocks[i]);
}
System.out.println("╠═══════════════╩═══════════╩════════╩══════════╣");
System.out.printf( "║ Valor total inventario: %12.2f € ║%n",
totalInventario);
System.out.printf( "║ Producto más caro (sin IVA): %-14s ║%n",
nombres[indiceMasCaro]);
System.out.printf( "║ Producto más barato (sin IVA):%-14s ║%n",
nombres[indiceMasBarato]);
System.out.println("╚═══════════════════════════════════════════════╝");
sc.close();
}
}
Visualízalo con Python Tutor
Selecciona Java en el desplegable y pega en pythontutor.com:
public class Demo {
public static void main(String[] args) {
// División entera vs cast correcto
int segundos = 90061;
// MAL — división entera antes del cast
double malPorcentaje = segundos / 86400 * 100;
// BIEN — cast antes de dividir
double bienPorcentaje = (double) segundos / 86400 * 100;
System.out.printf("Mal: %.2f%%%n", malPorcentaje);
System.out.printf("Bien: %.2f%%%n", bienPorcentaje);
// Búsqueda del máximo en un array
double[] precios = {899.99, 29.99, 79.99};
int indiceMasCaro = 0;
for (int i = 1; i < precios.length; i++) {
if (precios[i] > precios[indiceMasCaro]) {
indiceMasCaro = i;
}
}
System.out.println("Más caro en índice: " + indiceMasCaro);
System.out.println("Precio: " + precios[indiceMasCaro]);
}
}
Ejecuta paso a paso y observa dos momentos clave. Cuando se evalúa segundos / 86400 * 100, Python Tutor muestra que segundos / 86400 da 1 — entero — antes de que el resultado se asigne al double. El daño ya está hecho. En la segunda versión, el cast convierte segundos a 104156.0 antes de dividir y todo fluye como decimal. En el bucle de búsqueda del máximo, observa cómo indiceMasCaro empieza en 0 y solo cambia cuando encontramos un precio mayor — al final apunta al índice correcto sin necesidad de guardar el precio máximo por separado.
Chuletario — variables en Java
// ============================================
// CHULETARIO — Variables en Java
// Sergio Learns · sergiolearns.com
// ============================================
// TIPOS PRIMITIVOS — los que usarás en FP2
int i = 42; // enteros — el más común
double d = 3.14; // decimales — siempre double, no float
boolean b = true; // true o false — en minúsculas
char c = 'A'; // un carácter — comillas simples
// CONSTANTES — no cambian después de asignarse
final double PI = 3.14159;
final int MAX_ITEMS = 100;
// STRING — clase, no primitivo
String s = "hola";
// Métodos más usados:
s.length() // longitud
s.charAt(0) // carácter en posición 0
s.toUpperCase() // todo mayúsculas
s.toLowerCase() // todo minúsculas
s.trim() // quita espacios al inicio y final
s.equals("hola") // compara contenido — SIEMPRE esto
s.equalsIgnoreCase("HOLA") // igual pero sin importar mayúsculas
// LA REGLA DE ORO DE LOS STRINGS
s1.equals(s2) // ← CORRECTO — compara contenido
s1 == s2 // ← PELIGROSO — compara referencias de memoria
// WIDENING — automático, de menor a mayor tipo
int → long → double // Java lo hace solo, no hace falta cast
// NARROWING — manual, de mayor a menor tipo — puede perder datos
double d = 9.99;
int i = (int) d; // → 9 (trunca, NO redondea)
// Para redondear: (int) Math.round(d) → 10
// LA TRAMPA DE LA DIVISIÓN ENTERA
int a = 7, b = 2;
int mal = a / b; // → 3 (entera)
double bien = (double) a / b; // → 3.5 (cast ANTES)
double trampa = (double)(a / b); // → 3.0 (cast DESPUÉS — ya es tarde)
// MÓDULO Y DIVISIÓN ENTERA — muy útiles juntos
int total = 90061;
int dias = total / 86400; // cuántos días completos
int resto = total % 86400; // lo que sobra tras quitar los días
int horas = resto / 3600; // cuántas horas del resto
// ... y así hasta los segundos
// SCANNER — trampa del nextLine() después de nextInt/nextDouble
int edad = sc.nextInt();
sc.nextLine(); // ← SIEMPRE después de nextInt/nextDouble
String nombre = sc.nextLine(); // sin el nextLine() anterior, esto lee ""
// VALORES LÍMITE — útiles para detectar overflow
Integer.MAX_VALUE // 2.147.483.647 — máximo int
Integer.MIN_VALUE // -2.147.483.648 — mínimo int
Double.MAX_VALUE // número positivo más grande en double
// OPERADOR TERNARIO — para condiciones simples en una línea
String texto = (condicion) ? "valor si true" : "valor si false";
// Ejemplo:
String plural = (dias == 1) ? "día" : "días";
// PRINTF — especificadores más usados
%d → int
%f → double (%.2f = 2 decimales)
%s → String
%c → char
%b → boolean
%n → salto de línea en printf
%% → % literal
%10d → alineado a la derecha, 10 chars
%-10s → alineado a la izquierda, 10 chars
// MATH — funciones matemáticas más usadas
Math.abs(x) // valor absoluto
Math.pow(x, 2) // x elevado a 2
Math.sqrt(x) // raíz cuadrada
Math.round(x) // redondeo al entero más cercano
Math.max(a, b) // el mayor de dos valores
Math.min(a, b) // el menor de dos valores
Sigue aprendiendoTodos los artículos de Java
Un comentario