UD2 · Sección 10 — Ejercicios y actividades
| Dato | Valor |
|---|---|
| Unidad Didáctica | UD2 — Programación Orientada a Objetos con la API de Java |
| Resultado de Aprendizaje | RA2 — Escribe y prueba programas sencillos, reconociendo y aplicando los fundamentos de la programación orientada a objetos. |
| Sección | 10 de 10 — Ejercicios y actividades |
| Evaluación | 1.ª Evaluación |
| Duración estimada | 3 horas lectivas + trabajo autónomo |
| Criterios de evaluación cubiertos | CE 2.1 a CE 2.9 (cierre global del RA2) |
| Prerrequisitos | UD1 completa, UD2 Secciones 1 a 9 |
| Paquete del código de ejemplo | dam.programacion.ud2 |
| Herramientas | JDK 25, IntelliJ IDEA Community, Maven 3.9.x, JUnit 5 |
1. Punto de partida
Has llegado a la última sección de la unidad. A lo largo de las nueve anteriores has conocido los fundamentos de la POO, has aprendido a explorar el API de Java con Javadoc e IntelliJ, y has trabajado con las clases más usadas del JDK: String, Math, Random, java.time, StringBuilder, wrappers y Objects. También has dado tus primeros pasos con Maven y has escrito tus primeros tests con JUnit 5.
Esta sección no introduce teoría nueva: es el momento de poner en práctica todo lo aprendido en proyectos pequeños pero completos. Cada ejercicio se centra en una o varias clases del API y se resuelve combinando lo que ya sabes. Te presentamos el enunciado, una propuesta de solución totalmente funcional y, cuando procede, una pequeña variante para que la resuelvas tú.
La idea es que intentes cada ejercicio antes de mirar la solución. Es ahí, en el intento, donde realmente se consolidan los conceptos. La solución está para que la consultes cuando te atasques o para que compares tu enfoque con el nuestro.
Al final de la sección encontrarás la preparación para la prueba objetiva RA2, con el formato y los temas que entrarán.
2. Cómo abordar los ejercicios
Antes de empezar, unas pautas que te ahorrarán tiempo y frustración:
- Lee el enunciado completo antes de picar código. Asegúrate de entender qué se pide.
- Diseña antes de programar. Dedica uno o dos minutos a pensar qué clases del API vas a usar y en qué orden. Un diagrama mental o en papel ayuda.
- Escribe incrementalmente. No programes todo de golpe: haz una parte, ejecuta, verifica, y avanza. Es más fácil corregir un error en 5 líneas que en 50.
- Usa
System.out.printlnpara depurar. Imprime valores intermedios para ver qué pasa. - Consulta el Javadoc cuando dudes.
Ctrl+Qsobre cualquier clase o método te da la documentación. - No mires la solución hasta haberlo intentado. Aunque no logres completarlo, el proceso de intentarlo es donde se aprende.
- Compara tu solución con la propuesta. No hay una única forma correcta: si la tuya funciona y es legible, está bien.
Analogía del gimnasio. Aprender a programar es como entrenar en un gimnasio: leer la teoría es como ver vídeos de ejercicios, te dan idea de la técnica, pero el músculo solo crece cuando coges las pesas. Esta sección es la sala de pesas. El dolor muscular (frustración al depurar) es parte del proceso.
3. Ejercicio 1 — Manipulación de Strings: normalizador de emails
Enunciado
Escribe un programa que reciba un email tal y como lo escribe un usuario descuidado (con espacios, mayúsculas, puntos en sitios raros) y lo normalice:
- Eliminar espacios al principio y al final.
- Convertir todo a minúsculas.
- Sustituir cualquier espacio interno por un punto.
- Comprobar que contiene una
@y que termina en.com,.eso.org. - Devolver el email normalizado o un mensaje de error si no es válido.
Ejemplo:
- Entrada:
" Maria.Garcia @Example.COM " - Salida:
"maria.garcia@example.com"(válido) - Entrada:
"usuario#dominio.com" - Salida:
"Email invalido: falta la @"
Solución propuesta
Salida esperada:
Observación. Fíjate en la entrada " ana ruiz example es ": como hay varios espacios seguidos, la salida queda con .. (dos puntos). Una versión más completa del normalizador debería eliminar esos dobles puntos; te lo proponemos como variante.
Variante para ti
Mejora el método normalizar para que, después de sustituir espacios por puntos, no queden secuencias de dos o más puntos seguidos (usa replaceAll("\\.+", "."), que reemplaza una secuencia de uno o más puntos por un solo punto).
4. Ejercicio 2 — Cálculos con Math: estadísticas básicas
Enunciado
Dado un array de números (por ejemplo, las notas de un alumno), calcula:
- La nota máxima.
- La nota mínima.
- La media (redondeada a 2 decimales con
Math.round). - La desviación respecto a la media de cada nota (valor absoluto de la diferencia).
- La nota "aprobada" si la media es >= 5, "suspenso" en caso contrario.
Ejemplo:
- Entrada:
[7.5, 6.0, 8.2, 4.5, 9.1] - Salida:
Solución propuesta
Truco del redondeo a 2 decimales. Java no tiene un método directo para redondear a N decimales. El patrón estándar es:
Multiplicas por 10^N, redondeas al entero más cercano, y vuelves a dividir. Funciona porque Math.round elimina los decimales sobrantes.
Variante para ti
Añade al programa el cálculo de la desviación típica (raíz cuadrada de la media de los cuadrados de las desviaciones). Necesitarás Math.sqrt y otro bucle.
5. Ejercicio 3 — Generador de contraseñas con Random
Enunciado
Escribe un programa que genere contraseñas aleatorias cumpliendo estos requisitos:
- Longitud configurable (por defecto, 12 caracteres).
- Mezcla de mayúsculas, minúsculas, dígitos y símbolos especiales (
!@#$%&*). - Debe contener al menos una mayúscula, una minúscula, un dígito y un símbolo.
Utiliza ThreadLocalRandom por ser la mejor práctica moderna.
Solución propuesta
Salida (los valores cambian entre ejecuciones):
Detalles importantes:
- Uso de
ThreadLocalRandom.current()en lugar denew Random()por la recomendación moderna. - Garantía de requisitos: los 4 primeros caracteres ya cumplen los requisitos mínimos; el resto son aleatorios.
- Mezcla final: sin ella, los 4 primeros caracteres siempre serían
MAY-min-dig-simb, lo que reduce la entropía. El algoritmo de mezcla es el Fisher-Yates, clásico para barajar. - Uso de constantes
private static finalpara los conjuntos de caracteres (idea que verás en UD4).
Variante para ti
Añade un parámetro boolean incluirSimbolos que permita generar contraseñas sin símbolos (útil para sistemas que no los admiten). Adapta las garantías mínimas en consecuencia.
6. Ejercicio 4 — Fechas con java.time: cálculo de edad y días hasta el cumpleaños
Enunciado
Escribe un programa que, dada una fecha de nacimiento, calcule:
- La edad actual en años, meses y días (usando
Period). - Los días exactos que faltan para el próximo cumpleaños.
- El día de la semana en que caerá el próximo cumpleaños.
- La fecha formateada como "14 de julio de 2026" en español.
Solución propuesta
Nota sobre ChronoUnit. Es una enumeración que permite calcular diferencias en unidades específicas (días, meses, años, horas...). ChronoUnit.DAYS.between(a, b) devuelve el número total de días entre dos fechas. Es una alternativa a Period cuando solo te interesa una unidad.
Salida (parcial; depende de la fecha actual):
Variante para ti
Añade un método diasVividos que devuelva el número total de días desde el nacimiento hasta hoy. Pista: ChronoUnit.DAYS.between(nacimiento, hoy).
7. Ejercicio 5 — Informe con StringBuilder: reporte de ventas
Enunciado
Construye un informe de ventas a partir de un array de productos. Cada producto tiene nombre, unidades vendidas y precio unitario. El informe debe incluir:
- Cabecera con título y fecha.
- Línea separadora.
- Una línea por producto con el cálculo del subtotal (unidades × precio).
- Total general.
- Número de productos y media de subtotales.
Usa StringBuilder para construir el informe y String.join donde sea natural.
Solución propuesta
Salida esperada:
Patrones de String.format que se ven aquí:
| Patrón | Significado | Ejemplo |
|---|---|---|
%-15s |
String alineado a la izquierda, 15 caracteres de ancho | "Portatil " |
%3d |
Entero con 3 caracteres de ancho, rellenando con espacios | " 3" |
%8.2f |
Decimal con 8 caracteres de ancho, 2 decimales | " 899.99" |
%10.2f |
Decimal con 10 caracteres de ancho, 2 decimales | " 2699.97" |
%n |
Salto de línea portable | (depende del SO) |
"x".repeat(40) |
Repite la cadena 40 veces | "xxxx...x" |
Variante para ti
Añade al informe una columna "IVA (21%)" con el cálculo del IVA de cada producto, y una línea "Total con IVA" al final.
8. Ejercicio 6 — Mini-proyecto integrador: gestor de tareas
Enunciado
Combina todo lo aprendido en un pequeño gestor de tareas. Requisitos:
- Cada tarea tiene: descripción (String), fecha límite (
LocalDate), prioridad (alta/media/baja, como String) y completada (boolean). - Crea 5 tareas con datos diversos (alguna completada, alguna con fecha pasada, alguna con prioridad alta).
- Genera un informe que muestre:
- Tareas pendientes ordenadas por fecha límite (más urgente primero).
- Para cada tarea pendiente, los días que faltan (o "VENCIDA" si la fecha ya pasó).
- Estadísticas: total de tareas, completadas, pendientes, vencidas.
- Construye el informe con
StringBuildery formatea las fechas en español.
Nota. En este ejercicio usamos arrays paralelos para guardar las tareas. En UD4 aprenderás a crear una clase Tarea que agrupe todos los datos de una tarea en un objeto, lo que es mucho más limpio. Por ahora, los arrays paralelos nos sirven para no adelantar contenido.
Solución propuesta
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
Salida (parcial; depende de la fecha actual):
Observaciones:
- Este ejercicio combina elementos de todas las secciones anteriores:
String,LocalDate,ChronoUnit,StringBuilder,String.format, bucles, condicionales y ordenación. - La ordenación por selección es la más sencilla de entender para un principiante. En UD6 verás
List.sortcon comparadores, mucho más limpio. - Los arrays paralelos son un patrón provisional: en UD4 los sustituirás por una clase
Tarea.
Variante para ti
Añade al informe una sección "Tareas completadas" que muestre las ya hechas, con la descripción y la fecha límite que tenían.
9. Ejercicio 7 — Tests con JUnit 5: validar el normalizador de emails
Enunciado
Recupera el método normalizar del Ejercicio 1 y escribe tests con JUnit 5 que verifiquen:
- Que un email válido con espacios y mayúsculas se normaliza correctamente.
- Que un email sin
@devuelve el mensaje de error esperado. - Que un email con dominio no soportado devuelve el mensaje de error esperado.
- Que un email ya normalizado se mantiene igual.
Solución propuesta
Cómo ejecutarlos. En IntelliJ, clic derecho sobre la clase → "Run 'NormalizadorEmailTest'". Si los 5 tests pasan, verás la barra verde. Si alguno falla, IntelliJ te muestra el valor esperado y el recibido.
Variante para ti
Añade tests para casos límite: null, solo espacios, varios emails separados por comas. Recuerda que null puede lanzar NullPointerException; esto te dará pie a manejarlo en el método normalizar.
10. Actividad integradora: tu primer mini-proyecto
Como actividad final, te proponemos un mini-proyecto que integra todos los conceptos de la unidad. Elige una de las siguientes opciones:
Opción A: Gestor de biblioteca personal
Crea un programa que permita gestionar una pequeña biblioteca personal. Funcionalidades:
- Mantener un catálogo de libros (título, autor, fecha de compra, leído/no leído).
- Mostrar listado de libros pendientes de leer, ordenados por antigüedad.
- Calcular días desde la compra de cada libro.
- Generar un informe con
StringBuilderque incluya estadísticas (total, leídos, pendientes, media de días desde compra). - Tests con JUnit que validen el cálculo de días y las estadísticas.
Opción B: Simulador de citas médicas
Crea un programa que gestione citas médicas. Funcionalidades:
- Mantener un listado de citas (paciente, fecha y hora, médico, motivo).
- Mostrar próximas citas ordenadas por fecha.
- Calcular minutos hasta la próxima cita.
- Identificar citas pasadas (ya atendidas o no show).
- Generar un informe con
StringBuilder. - Tests con JUnit que validen el cálculo de tiempo hasta la próxima cita.
Opción C: Calculadora de presupuesto doméstico
Crea un programa que gestione gastos mensuales. Funcionalidades:
- Mantener un listado de gastos (concepto, importe, fecha, categoría).
- Mostrar gastos ordenados por importe descendente.
- Calcular total gastado, gasto medio, gasto máximo y mínimo.
- Calcular días desde el último gasto.
- Generar un informe mensual con
StringBuilderyString.format. - Tests con JUnit que validen los cálculos.
Cómo entregarlo
- Crea un proyecto Maven en IntelliJ con paquete
dam.programacion.ud2. - Implementa el programa en una clase principal (
Main,GestorBiblioteca, etc.). - Escribe al menos 5 tests con JUnit 5 que validen las funcionalidades clave.
- Sube el proyecto a Git (lo verás en el módulo de Entornos de Desarrollo) o entrégalo en un
.zipsegún indique tu profesor. - Asegúrate de que
mvn testpasa todos los tests antes de entregar.
Criterios de evaluación del mini-proyecto:
| Criterio | Peso |
|---|---|
| Funcionalidad: cumple los requisitos | 40% |
Uso correcto de las clases del API (String, LocalDate, StringBuilder, etc.) |
20% |
| Calidad del código: nombres claros, comentarios, indentación | 15% |
| Tests: cubren los casos importantes y pasan | 15% |
Estructura Maven: pom.xml correcto, paquetes bien organizados |
10% |
11. Preparación para la prueba objetiva RA2
La prueba objetiva RA2 es un examen de 90 minutos, sin material, que combina teoría y práctica. Aquí tienes la guía de preparación.
11.1. Formato del examen
| Bloque | Tipo | Peso aproximado |
|---|---|---|
| Bloque teórico | 10-15 preguntas de elección múltiple y cortas | 30% |
| Bloque práctico | 2-3 ejercicios de código | 70% |
11.2. Temas que entran
Todo lo visto en las secciones 1 a 9 de UD2:
| Tema | Puntos clave |
|---|---|
| Pilares de la POO | Clase vs. objeto, new, heap vs. stack, operador punto, encapsulación, abstracción, herencia, polimorfismo |
| API de Java | Paquetes (java.lang, java.util, java.time), Javadoc, métodos de instancia vs. estáticos |
String |
Inmutabilidad, pool, búsqueda, transformación, extracción, comparación, formatted |
Math |
Constantes, abs, max, min, clamp, redondeo, potencia, trigonometría, random |
Random y ThreadLocalRandom |
Semilla, reproducibilidad, nextInt, nextDouble, nextBoolean, nextGaussian |
java.time |
LocalDate, LocalTime, LocalDateTime, Period, Duration, DateTimeFormatter |
StringBuilder |
Mutabilidad, append, insert, delete, replace, reverse, StringJoiner, String.join |
Wrappers y Objects |
Autoboxing/unboxing, constantes, parseXxx, Objects.requireNonNull, equals seguro |
| Maven | pom.xml, coordenadas GAV, dependencias, ciclo de vida, estructura de carpetas |
11.3. Temas que NO entran (por estar en unidades posteriores)
- Clases propias, constructores,
this,private/public(UD4) - Excepciones y
try-catch(UD3) - Colecciones (
List,Set,Map) y Streams (UD6) - Herencia con
extends, interfaces (UD4, UD7) - JavaFX (UD5)
11.4. Consejos para el examen
- Lee todo el examen antes de empezar. Empieza por lo que te sepas mejor; deja lo difícil para el final.
- En los ejercicios prácticos, escribe el
importsiempre. Muchos puntos se pierden por olvidar elimport. - No uses
==con strings. Usa.equals(). Es un error clásico que resta puntos. - Recuerda la inmutabilidad. Si escribes
s.toUpperCase();sin asignar, no pasa nada. Hay que hacers = s.toUpperCase();. - En
LocalDate, los meses van de 1 a 12. No de 0 a 11 como enCalendar. - Si no recuerdas un método exacto, escribe el más plausible. Un método con nombre razonable y firma correcta suele tener penalización menor que dejarlo en blanco.
- Gestiona el tiempo. Si un ejercicio te lleva más de 25 minutos, déjalo y vuelve al final.
- Revisa al terminar. Comprueba que los
importestán, que los métodos se llaman correctamente y que no hay;olvidados.
11.5. Ejemplo de pregunta teórica
Pregunta. ¿Cuál es la diferencia entre
==y.equals()al comparar dos strings en Java? Pon un ejemplo donde==devuelvafalsepero.equals()devuelvatrue.
Respuesta modelo. == compara referencias (direcciones de memoria); .equals() compara contenidos. Por ejemplo:
a y b son referencias distintas a dos objetos String distintos, aunque su contenido sea idéntico. Por eso == devuelve false, pero .equals(), que compara caracteres, devuelve true.
11.6. Ejemplo de ejercicio práctico
Enunciado. Escribe un programa que: 1. Cree un
LocalDatecon la fecha actual. 2. Calcule la fecha correspondiente a dentro de 30 días. 3. Genere unStringBuildercon el texto:"En 30 dias sera <fecha formateada como dd/MM/yyyy>". 4. Imprima el resultado.
Solución modelo.
12. Cierre de la unidad
Has llegado al final de la UD2. A lo largo de diez secciones has pasado de "¿qué es una clase?" a manejar con soltura las clases más importantes del API estándar de Java, escribir tests automáticos y entender cómo se gestiona un proyecto profesional con Maven.
Lo que has aprendido:
- Los cuatro pilares de la POO y cómo se materializan en el API de Java.
- Leer y entender documentación Javadoc.
- Trabajar con
String(inmutable, métodos de búsqueda, transformación, comparación). - Hacer cálculos con
Mathy generar aleatorios conRandomyThreadLocalRandom. - Manejar fechas y horas con
java.time. - Construir textos eficientemente con
StringBuilder. - Usar wrappers y
Objectspara casos donde los primitivos no bastan. - Gestionar dependencias externas con Maven y escribir tests con JUnit 5.
Lo que viene en UD3:
La siguiente unidad, "Control de Flujo y Depuración", te dará las herramientas para que tus programas tomen decisiones y repitan acciones: if, switch expression, bucles for, while, do-while, gestión de excepciones con try-catch-finally y depuración con IntelliJ. Es una unidad esencial porque sin control de flujo, ningún programa hace nada realmente interesante. Hemos ido usando algo de if y de for a lo largo de la UD2 como aperitivo, pero ahora los estudiaremos a fondo.
Mensaje final. Aprender a programar es un proceso largo. Lo importante no es que recuerdes todos los métodos de String o que sepas escribir un StringBuilder perfecto en el primer intento. Lo importante es que entiendas la lógica subyacente y sepas buscar lo que no recuerdes. Cualquier programador profesional consulta el Javadoc a diario; tú ya sabes hacerlo. Esa es tu verdadera superpotencia.
Sigue practicando. La única forma de aprender a programar es programando. Nos vemos en la UD3.
13. Información ampliada y próximos pasos
- Ejercicios de Programación en Java (Java Exercises, w3resource): https://www.w3resource.com/java-exercises/
- CodingBat Java (ejercicios cortos de lógica): https://codingbat.com/java
- Baeldung (tutoriales prácticos): https://www.baeldung.com/
- Documentación de JUnit 5: https://junit.org/junit5/docs/current/user-guide/
Próximos pasos:
- Resuelve los 7 ejercicios propuestos sin mirar las soluciones. Si te atasques, consulta y vuelve a intentarlo.
- Elige una de las tres opciones de mini-proyecto y desarrollela completamente en IntelliJ con tests. Es la mejor forma de consolidar.
- Repasa el cuestionario de cada sección unos días antes del examen. Si fallas alguna pregunta, vuelve a la sección correspondiente.
- Practica en papel. En el examen no tendrás IntelliJ ni autocompletado. Escribe a mano pequeños programas para acostumbrarte.
- Avanza a la UD3 cuando hayas superado la prueba objetiva RA2. La UD3 te dará el control de flujo y las excepciones que necesitas para que tus programas empiecen a hacer cosas realmente interesantes.