7. Iteración: for-each (enhanced for)
UD3 — Control de Flujo y Depuración · RA3 — Escribe y depura código, analizando y utilizando las estructuras de control del lenguaje
| Aspecto | Valor |
|---|---|
| Resultado de aprendizaje | RA: 3 — Escribe y depura código, analizando y utilizando las estructuras de control del lenguaje. |
| Criterios de evaluación a los que contribuye esta sección | CE 3.2 (utiliza estructuras de repetición) CE 3.5 (crea programas ejecutables combinando estructuras de control) CE 3.7 (comenta y documenta el código). |
| Marco normativo | RD 405/2023 · RD 450/2010 · RD 659/2023 |
| Tecnología base | Java 25 LTS (OpenJDK Temurin 25) — soporte hasta 2030+ |
| Horas estimadas | ~2 h (de las 30 h de la UD3). |
Requisitos previos (lo que ya sabes): condiciones booleanas y operadores lógicos (sección 1 de UD3);
if/else if/else, early return, validación conIO.readlnyif(sección 2 de UD3);switchexpression con flecha y múltiples etiquetas (sección 3 de UD3);whileydo-while(sección 4 de UD3); arrays unidimensionales como tipo compuesto (declaración, inicialización,.length, acceso por índice, valores por defecto,String.toCharArray(), swap) — sección 5 de UD3;forclásico sobre arrays y Strings, incluyendo variantes (decreciente, saltos, múltiples variables) y utilidades deArrays(copyOf,sort,binarySearch,toString) — sección 6 de UD3. Tipos primitivos,var,String(con.equals(),.equalsIgnoreCase(),.length(),.trim(),.toLowerCase(),.charAt()),text blocks,finalpara constantes y operador ternario (de UD1).
7.1 ¿De qué va esta sección? — Recorrer sin índice
En la sección 6 aprendiste el for clásico y viste que es la herramienta natural para recorrer arrays. Lo usaste para sumar elementos, buscar el máximo, modificar un array, recorrerlo al revés, saltar posiciones, recorrer dos arrays en paralelo, etc.
Pero hay un patrón muy común en el que el for clásico es más verboso de lo necesario: cuando simplemente quieres recorrer todos los elementos en orden, sin necesidad de índice. Mira este ejemplo de la sección 6:
Fíjate en lo que has escrito: declaras i, comparas i < numeros.length, incrementas i, y dentro del bloque usas numeros[i]. Toda esa maquinaria (inicialización, condición, actualización, acceso por índice) solo sirve para ir pasando por cada elemento. No estás haciendo nada especial con el índice i: lo usas como un "contador de posición" que en realidad no te interesa.
Java (desde la versión 5, de 2004) tiene una sintaxis más simple para este caso: el for-each (también llamado enhanced for o "for mejorado"). El mismo código, escrito con for-each, queda así:
Fíjate: no hay índice. No hay i, no hay i < length, no hay i++. Simplemente dices "para cada int n del array numeros, haz esto". Java se encarga de ir pasando al siguiente elemento por ti.
En esta sección vas a aprender el for-each a fondo. Cubriremos, en este orden:
- Sintaxis del for-each y su anatomía.
- Cómo funciona paso a paso.
- Ejemplos básicos: sumar, buscar máximo, contar elementos que cumplen una condición.
- for-each con arrays de
String. - for-each con caracteres de un
StringusandotoCharArray()(que ya conoces de la sección 5). - for-each vs
forclásico: cuándo elegir cada uno (la regla de oro). - La limitación del for-each: no modifica el array (la variable del for-each es una copia).
- Trampas clásicas del for-each.
- Ejemplos resueltos paso a paso.
Analogía del repartidor de folletos
Imagina que tienes que repartir folletos a 50 personas que están en una cola. Con for clásico, sería como si gritaras: "¡Número 0, toma un folleto! ¡Número 1, toma un folleto! ¡Número 2, toma un folleto!". Tienes que llevar la cuenta del número en todo momento. Con for-each, es como si simplemente fueras caminando por la cola y le dieras un folleto a cada persona, sin importar su número. Mucho más natural, mucho menos que pensar.
Vamos a empezar por la sintaxis, que es lo más simple del mundo.
7.2 Sintaxis del for-each
7.2.1 Anatomía
La sintaxis del for-each es así:
Partes:
Tipo elemento: declaras una variable local del tipo de los elementos que vas a recorrer. Esta variable existe solo dentro del bucle y en cada iteración toma el valor del siguiente elemento.:(dos puntos): se lee como "en" o "de".for (int n : numeros)se lee "para cadanennumeros" o "para cadandenumeros".array: el array que vas a recorrer (en UD6 verás que también funciona con colecciones).{ ... }: el bloque que se ejecuta una vez por cada elemento. Dentro del bloque,elementocontiene el valor actual.
7.2.2 Cómo funciona paso a paso
Vamos a verlo con un ejemplo pequeño:
Salida:
Paso a paso:
- Java toma
numeros[0](que es10), lo asigna an, y ejecuta el bloque. Se imprime "El valor actual es: 10". - Java toma
numeros[1](que es20), lo asigna an, y ejecuta el bloque. Se imprime "El valor actual es: 20". - Java toma
numeros[2](que es30), lo asigna an, y ejecuta el bloque. Se imprime "El valor actual es: 30". - Java se da cuenta de que no hay más elementos. Sale del bucle.
Fíjate: no hay índice. Tú no controlas i, no hay i++, no hay i < length. Java hace todo ese trabajo por ti y te entrega cada elemento listo para usar.
7.2.3 Lectura recomendada
La convención para leer el for-each en voz alta es:
"Para cada
elementodearray, haz..."
Ejemplo:
Se lee: "Para cada nombre de nombres, imprime 'Hola, ' más el nombre". Es prácticamente prosa.
7.2.4 Diagrama de flujo
flowchart TD
Inicio([Inicio]) --> Init["Prepara el primer elemento"]
Init --> Condicion{"¿Hay más\nelementos?"}
Condicion -->|Sí| Asigna["elemento = siguiente\nelemento del array"]
Asigna --> Cuerpo["Bloque del bucle\n(usas 'elemento')"]
Cuerpo --> Condicion
Condicion -->|No| Fin([Fin del bucle])
Fíjate que la estructura es la misma que un while: comprobar, ejecutar, volver a comprobar. La diferencia es que el for-each oculta toda la maquinaria del índice y te entrega el elemento directamente.
7.2.5 El for-each SIEMPRE recorre todo
Una característica importante: el for-each recorre todos los elementos del principio al final, sin excepción. No puedes:
- Empezar por el medio.
- Saltar elementos.
- Ir de atrás hacia adelante.
- Parar antes de tiempo (salvo con
break, que se ve en la sección 8).
Si necesitas alguna de esas cosas, tienes que usar for clásico o while. El for-each es para "quiero pasar por todos, en orden, sin más".
7.2.6 El for-each con diferentes tipos de arrays
Funciona con cualquier tipo de array. Solo tienes que declarar la variable con el tipo correcto:
La regla: el tipo de la variable del for-each tiene que coincidir con el tipo de los elementos del array. Si el array es int[], la variable es int. Si es String[], la variable es String. Y así con todos.
7.3 Ejemplo básico: sumar todos los elementos
Vamos con el ejemplo más clásico de todos: sumar los elementos de un array de números.
Paso a paso:
- Declaramos el array
numeroscon 5 valores. - Inicializamos
suma = 0(el acumulador). - Para cada
nennumeros: - Iteración 1:
n = 10,suma = 0 + 10 = 10. - Iteración 2:
n = 20,suma = 10 + 20 = 30. - Iteración 3:
n = 30,suma = 30 + 30 = 60. - Iteración 4:
n = 40,suma = 60 + 40 = 100. - Iteración 5:
n = 50,suma = 100 + 50 = 150. - Salida: "La suma es: 150".
Detalles importantes:
sumase declara fuera del bucle. Si la declararas dentro, se reiniciaría en cada iteración y al final tendrías solo el último valor.nse declara dentro del for-each. En cada iteración,ntoma un valor nuevo; al terminar el bucle,ndeja de existir.- El acumulador empieza en 0 (para sumar) o en 1 (para multiplicar). Es el patrón "acumulador" que ya viste en la sección 6.
7.3.1 Patrón general: acumulador con for-each
El patrón "recorrer y acumular" es uno de los más comunes en programación. La estructura es siempre la misma:
Ejemplos de variantes:
El patrón siempre es: inicializar fuera, modificar dentro. Si inicializas dentro, lo pierdes en cada iteración.
7.4 for-each con arrays de String
El for-each funciona igual con cualquier tipo. Veamos un ejemplo con String[].
7.4.1 Saludar a cada alumno
Salida:
7.4.2 Buscar el nombre más largo
Detalles:
masLargose inicializa connombres[0](el primero). Es un patrón típico de "buscar el máximo".- En cada iteración comparamos
nombre.length()conmasLargo.length(). Si el actual es más largo, lo guardamos. - Al final del bucle,
masLargocontiene el más largo de todos.
7.4.3 Contar cuántos nombres empiezan por una letra
Detalles:
nombre.charAt(0)devuelve el primer carácter del String. El métodocharAtse ve en profundidad en UD2; aquí lo usamos como ya lo has hecho.!nombre.isEmpty()es una defensa: si el array tuviera un String vacío"", llamar acharAt(0)lanzaríaStringIndexOutOfBoundsException. Comprobando primero que no esté vacío, nos protegemos.
7.5 for-each con caracteres de un String: el truco toCharArray()
Hay un caso especial muy útil: recorrer los caracteres de un String uno a uno. Por ejemplo, contar cuántas vocales tiene una palabra.
El problema: String no se puede recorrer directamente con for-each. No puedes escribir for (char c : "hola") { ... } porque el compilador da error. Un String no es una colección de caracteres desde el punto de vista del for-each.
La solución: el método toCharArray() de String (que ya conoces de la sección 5) devuelve un char[] con todos los caracteres. Y un char[] sí se puede recorrer con for-each.
Salida:
Detalles:
texto.toCharArray()devuelve{'P', 'r', 'o', 'g', 'r', 'a', 'm', 'a', 'c', 'i', 'ó', 'n', ' ', 'e', 'n', ' ', 'J', 'a', 'v', 'a', ' ', '2', '5'}. Cada carácter, incluidos los espacios, es un elemento del array.Character.toLowerCase(c)convierte el carácter a minúscula antes de comparar, para no tener que mirara,A,e,E, etc. por separado. El métodoCharacterse ve en UD2; aquí lo usamos como "caja negra".
7.5.1 Otro ejemplo: contar mayúsculas
Detalles:
c >= 'A' && c <= 'Z'comprueba sices una mayúscula sin acento. Es la forma "manual" sin usarCharacter.isUpperCase(c)(que verás en UD2).- Este método no cuenta la Ñ ni las vocales acentuadas (Á, É, Í, Ó, Ú, Ü). Para hacerlo bien, lo ideal es
Character.isUpperCase(c). Aquí mostramos la versión "manual" para que veas la lógica, no porque sea la mejor.
7.5.2 ¿Por qué toCharArray() y no charAt con for clásico?
En la sección 6 viste que podías recorrer un String con for clásico y charAt(i) sin crear un array nuevo:
Aquí con for-each necesitas toCharArray() porque el for-each no puede recorrer un String directamente (no es un array ni una colección). Tienes que convertirlo primero.
¿Cuál es mejor?
| Criterio | charAt(i) con for clásico |
toCharArray() con for-each |
|---|---|---|
| ¿Crea un array nuevo? | No (más eficiente en memoria). | Sí (crea un char[] nuevo). |
| ¿Sintaxis? | Más verboso (texto.charAt(i)). |
Más limpio (char c : arr). |
| ¿Permite for-each? | No. | Sí. |
| ¿Recomendado para... | Recorridos simples, eficiencia. | Casos donde quieres for-each o modificar el array. |
Regla del profesor:
Para recorrer un
Stringcon for-each, usatoCharArray(). Si quieres eficiencia máxima o no necesitas for-each, usacharAt(i)con for clásico (sección 6).
7.6 for-each vs for clásico: cuándo elegir cada uno
Esta es la decisión más importante de esta sección. Tienes dos bucles que parecen hacer lo mismo (recorrer un array), pero no son intercambiables. Elegir bien al principio te ahorra bugs y hace el código más legible.
7.6.1 Tabla comparativa
| Criterio | for clásico |
for-each |
|---|---|---|
| ¿Necesitas el índice? | Sí, es la opción. | No, no lo tienes. |
| ¿Quieres recorrer todo, en orden, sin más? | Funciona, pero verboso. | Mejor for-each. |
| ¿Quieres saltar elementos? | Sí, puedes con i += 2. |
No, recorre todo. |
| ¿Quieres ir de atrás adelante? | Sí, for (int i = n-1; i >= 0; i--). |
No. |
| ¿Quieres modificar elementos del array? | Sí, con arr[i] = .... |
No, elemento es una copia. |
| ¿Recorres dos arrays en paralelo? | Sí, con arr1[i] y arr2[i]. |
No, necesitarías dos bucles. |
¿Necesitas parar antes con break? (sección 8) |
Sí, con break. |
Sí, con break. |
| ¿Código más legible para recorrido simple? | Más verboso. | Más limpio. |
¿Riesgo de error off-by-one? (< vs <=) |
Sí. | No, no hay índice. |
7.6.2 La regla de oro
"Si no necesitas el índice, usa for-each. Si lo necesitas, usa for clásico."
Esa es toda la decisión. El for-each es menos potente pero más seguro y más legible. El for clásico es más potente pero más propenso a errores (off-by-one, índice mal calculado, etc.).
7.6.3 Ejemplos: cuándo elegir cada uno
Caso 1: Sumar todos los elementos.
→ for-each.
Caso 2: Imprimir cada elemento con su posición.
→ for clásico.
Caso 3: Modificar los elementos del array (por ejemplo, multiplicar todos por 2).
→ for clásico. (Más sobre esto en 7.7.)
Caso 4: Recorrer solo los elementos en posiciones pares.
→ for clásico.
Caso 5: Buscar el máximo de un array.
→ for-each.
7.6.4 Resumen mental
flowchart TD
A["¿Quieres recorrer un array?"] --> B{"¿Necesitas el índice?"}
B -->|No| C{"¿Solo recorrer en orden\nsin saltar ni invertir?"}
C -->|Sí| D["**for-each**"]
C -->|No| E["**for clásico**"]
B -->|Sí| E
D --> F["Fin"]
E --> F
Esta es la decisión más importante de la sección. Si te la aprendes, no te equivocarás nunca al elegir bucle.
7.7 La limitación del for-each: no modificar el array
Esta es la trampa más importante del for-each y la que más bugs provoca. Vamos a verla con detalle.
7.7.1 El problema: elemento es una copia
Cuando escribes for (int n : numeros), en cada iteración Java hace algo parecido a:
Es decir: n es una copia del valor, no una referencia al elemento del array. Si modificas n, no modificas el array. Mira:
Salida:
El array no ha cambiado. Lo que has hecho es multiplicar por 2 una copia local n que se descarta en cada iteración.
7.7.2 La solución: usar for clásico
Si necesitas modificar los elementos del array, tienes que usar for clásico y acceder por índice (como viste en la sección 6):
Salida:
Ahora sí ha cambiado, porque en cada iteración modificamos numeros[i], no una copia.
7.7.3 ¿Qué pasa con arrays de String?
Con String, que es inmutable (no se puede cambiar su contenido), no puedes modificar el contenido de ningún elemento. Lo máximo que puedes hacer con for clásico es reemplazar un elemento por otro:
Con for-each, esto no funcionaría porque nombre es una copia de la referencia, y reasignarla no afecta al array:
7.7.4 Regla mnemotécnica
"for-each lee, for clásico escribe."
Si solo vas a leer los elementos (sumarlos, buscarlos, imprimirlos), for-each. Si vas a modificar los elementos (cambiar valores, reemplazar), for clásico.
7.7.5 Adelanto de UD6: modificación de estructura
Cuando veas las colecciones (List, Set) en UD6, descubrirás otra limitación: no puedes añadir ni eliminar elementos de una colección mientras la recorres con for-each. Java lanza ConcurrentModificationException para protegerte. En los arrays esto no aplica (no se pueden redimensionar), pero la idea es la misma: el for-each es para leer, no para modificar la estructura que recorres. Las colecciones se ven en UD6.
7.8 Errores típicos del for-each
Antes de pasar a los ejemplos, repasamos las trampas más típicas.
7.8.1 pensar que elemento modifica el array
Ya lo vimos en 7.7: for (int n : arr) { n = ...; } no modifica arr. La variable n es una copia.
Solución: si quieres modificar, usa for clásico con arr[i] = ....
7.8.2 declarar el tipo incorrecto
Solución: el tipo de la variable del for-each tiene que coincidir con el tipo de los elementos del array.
7.8.3 usar for-each cuando necesitas el índice
Solución: si necesitas el índice, usa for clásico.
7.8.4 recorrer un array vacío
Salida:
Si el array tiene 0 elementos, el for-each no ejecuta el bloque ni una sola vez. No es un error, pero puede sorprenderte si esperabas que imprimiera algo. Es equivalente a un for (int i = 0; i < 0; i++) que tampoco entra.
Solución: si necesitas manejar el caso vacío de forma especial, comprueba array.length == 0 antes del bucle.
7.8.5 recorrer un array null
Si el array es null (no vacío, sino null), el for-each lanza NullPointerException. Lo mismo pasa con for clásico al evaluar nulo.length.
Solución: comprueba null antes:
7.8.6 confundir la sintaxis con la del for clásico
El for-each no tiene condición ni actualización. Solo Tipo elemento : array. Si necesitas condición o actualización, usa for clásico.
7.8.7 intentar recorrer un String directamente
Solución: llama a toCharArray() para convertir el String en un char[] que sí se pueda recorrer.
7.9 Ejemplos resueltos paso a paso
Cinco ejemplos completos que integran todo lo aprendido.
7.9.1 Ejemplo 1: estadísticas de un array de notas
Salida:
Puntos clave:
- Cuatro for-each distintos, cada uno con un propósito. Se podría haber hecho todo en un solo for clásico (más eficiente), pero así el código queda más legible: cada bucle hace una sola cosa.
maxyminse inicializan connotas[0], no con0ni conDouble.MAX_VALUE. Es la forma más segura.Arrays.toStringpara imprimir el array de golpe (utilidad de la sección 6).- No hay
importparaIO(es dejava.lang).
7.9.2 Ejemplo 2: buscar un nombre en un array
Puntos clave:
equalsIgnoreCasepara no distinguir mayúsculas: si el usuario escribe"ana"o"ANA", encuentra a"Ana".boolean encontrado = falsees una "bandera": la ponemos atruecuando encontramos el nombre.- Cuando veamos
break(sección 8), podremos salir del bucle en cuanto encontremos el nombre, sin esperar a recorrer todo el array. Por ahora, el bucle termina solo cuando se acaba el array. - Después del bucle, comprobamos la bandera y damos el mensaje. Es el patrón "buscar y reportar".
7.9.3 Ejemplo 3: contar vocales de una frase
Salida con "Hola, mundo":
Puntos clave:
toCharArray()para recorrer los caracteres de unStringcon for-each.- Tres contadores para tres categorías mutuamente excluyentes.
- Variables auxiliares
esVocalyesConsonante. - Vocales con acento (
á,é,í,ó,ú) están incluidas enesVocal. Es un detalle que mucha gente olvida.
7.9.4 Ejemplo 4: validar que todas las notas son aprobadas
Puntos clave:
- Patrón "todas cumplen": empiezas asumiendo que todas son
true, y si encuentras una sola que no cumple, lo pones afalse. Es el patrón inverso al "buscar uno": aquí buscas un contraejemplo. final double NOTA_APROBADO = 5.0: constante sin magic number.- Con
break(sección 8), en cuanto encuentres una suspensa puedes salir del bucle. Por ahora, el bucle termina solo al final del array.
7.9.5 Ejemplo 5: menú con for-each para listar
Puntos clave:
- Combinación de switch (sección 3) y for-each (esta sección): el switch decide qué hacer, y dentro de cada
casese usa for-each para recorrer un array. - Cada
casedeclara su propio arrayalumnoslocal al bloque. Es legal porque cada bloque tiene su propio ámbito. - Patrón "listar opciones": recorrer un array para mostrarlo al usuario. Muy común en menús.
7.10 Buenas prácticas del for-each
7.10.1 Las 8 reglas del for-each profesional
- for-each para leer, for clásico para escribir. Si solo recorres, for-each. Si modificas, for clásico.
- El tipo de la variable tiene que coincidir con el del array.
int[]→int,String[]→String. - Declara el acumulador fuera del bucle. Si lo declaras dentro, se reinicia en cada iteración.
- Inicializa máximos y mínimos con
array[0], no con0ni con constantes mágicas. - No lleves un contador manual dentro del for-each para imitar el índice: si necesitas el índice, usa for clásico.
- Comprueba
nullantes si hay riesgo de que el array seanull. - Usa
toCharArray()para recorrer caracteres de unStringcon for-each. - Cuando llegues a colecciones (UD6), recuerda que no puedes añadir/eliminar durante el recorrido.
7.10.2 Cuándo refactorizar
| Síntoma | Refactoriza a |
|---|---|
for clásico que solo recorre y usa arr[i] sin tocar i. |
for-each. |
for-each con un contador manual int i = 0; que vas incrementando. |
for clásico (necesitas el índice). |
for-each que intenta modificar elemento. |
for clásico con arr[i] = .... |
for-each sobre un String que da error de compilación. |
toCharArray(). |
7.10.3 Comentar el for-each
Los comentarios buenos en un for-each explican qué estás calculando, no el bucle en sí:
7.11 Glosario rápido
| Término | Significado |
|---|---|
for-each |
Bucle que recorre todos los elementos de un array sin índice. También llamado enhanced for. |
enhanced for |
Nombre alternativo de for-each. |
elemento |
Variable del for-each que en cada iteración toma el valor del siguiente elemento. |
iterable |
Lo que se puede recorrer con for-each: arrays (UD3) o cualquier cosa que implemente Iterable<T> (UD6). |
Iterable<T> |
Interfaz de Java que permite el recorrido con for-each. Se ve en UD6. |
toCharArray() |
Método de String que devuelve un char[] con todos los caracteres. Útil para for-each. |
| Acumulador | Variable que se inicializa fuera del bucle y se modifica dentro para sumar, multiplicar, contar, etc. |
ConcurrentModificationException |
Excepción que lanza Java si modificas la estructura de una colección durante el recorrido (UD6). |
| Búsqueda lineal | Recorrer todos los elementos hasta encontrar el buscado. Es lo que hace for-each cuando buscas. |
7.12 Actividades propuestas
Cinco actividades graduadas. Hazlas en orden. Las soluciones se publicarán en Aules.
7.12.1 Actividad 1 — Estadísticas de un array de temperaturas
Objetivo: practicar for-each con varios patrones de acumulación.
Enunciado: Dado un array de temperaturas de una semana:
Calcula con for-each (un bucle por cada métrica):
- La suma de todas las temperaturas.
- La media (suma / número de elementos).
- La temperatura máxima.
- La temperatura mínima.
- Cuántos días han estado por encima de la media.
Muestra los resultados con String.format("%.2f", valor) para los decimales.
Entrega: archivo EstadisticasTemperaturas.java en el paquete jams.programacion.ud3.
Criterios evaluados: CE 3.2, CE 3.5, CE 3.7.
7.12.2 Actividad 2 — Buscar y contar en un array de nombres
Objetivo: practicar for-each con búsqueda y conteo.
Enunciado: Dado un array de nombres de la clase:
Pide al usuario una letra (una sola, leída con IO.readln().charAt(0)). Recorre el array con for-each y muestra:
- Cuántos nombres empiezan por esa letra (sin distinguir mayúsculas/minúsculas).
- La lista de esos nombres, uno por línea.
Requisitos:
- Usa
Character.toLowerCase(nombre.charAt(0))para comparar sin distinguir mayúsculas. - Comprueba que el nombre no esté vacío antes de llamar a
charAt(0). - Si no hay ningún nombre con esa inicial, muestra "No hay nombres que empiecen por 'X'."
Entrega: archivo BuscarPorInicial.java en el paquete jams.programacion.ud3.
Criterios evaluados: CE 3.2, CE 3.5, CE 3.7.
7.12.3 Actividad 3 — Analizador de frase
Objetivo: combinar for-each con toCharArray() y patrones de conteo.
Enunciado: Pide al usuario una frase con IO.readln(). Recórrela con for-each sobre toCharArray() y muestra:
- Número total de caracteres (incluyendo espacios).
- Número de vocales (incluyendo acentuadas: á, é, í, ó, ú).
- Número de consonantes (letras sin acento, sin vocales).
- Número de espacios.
- Número de dígitos (caracteres del '0' al '9').
- Número de "otros" (signos de puntuación, símbolos, etc.).
Requisitos:
- Usa métodos auxiliares
esVocal(char),esConsonante(char),esDigito(char),esEspacio(char)definidos fuera delmain(copia la sintaxis del ejemplo 7.9.3). - Define una constante
final String VOCALES = "aeiouáéíóúAEIOUÁÉÍÓÚ";y comprueba conVOCALES.indexOf(c) >= 0enesVocal.
Entrega: archivo AnalizadorFrase.java en el paquete jams.programacion.ud3.
Criterios evaluados: CE 3.2, CE 3.5, CE 3.7.
7.12.4 Actividad 4 — Comparativa for-each vs for clásico
Objetivo: entender cuándo elegir cada bucle.
Enunciado: Dado el array:
Implementa las dos versiones (for-each y for clásico) de cada tarea y comenta cuál es más adecuada:
- Sumar todos los elementos.
- Imprimir cada elemento con su índice:
"Posición 0: 3","Posición 1: 7", etc. - Duplicar todos los elementos del array (modificar el propio array).
- Imprimir solo los elementos en posiciones pares (0, 2, 4, 6, 8).
- Buscar el máximo.
Tareas:
- Para cada tarea, escribe ambas versiones (for-each y for clásico).
- Comenta al final (en un comentario de bloque
/* ... */): ¿cuál es más adecuada en cada caso y por qué?
Entrega: archivo ComparativaBucles.java en el paquete jams.programacion.ud3, con las 10 versiones (5 tareas × 2 bucles) y la comparativa comentada al final.
Criterios evaluados: CE 3.2, CE 3.5, CE 3.7.
7.12.5 Actividad 5 — Cuestionario de repaso
Responde por escrito:
- ¿Cuál es la sintaxis del for-each y cómo se lee en voz alta?
- ¿Qué tres cosas NO puedes hacer con for-each que sí puedes con for clásico?
- ¿Por qué modificar
elementodentro del for-each no cambia el array? - ¿Cuándo elegirías for-each y cuándo for clásico?
- ¿Cómo recorres los caracteres de un
Stringcon for-each? - ¿Qué pasa si recorres con for-each un array vacío?
- ¿Qué pasa si recorres con for-each un array
null? - ¿Con qué otros tipos (además de arrays) funciona el for-each? ¿Cuándo se ven?
- ¿Qué es
ConcurrentModificationExceptiony cuándo aparece? - Escribe el patrón "buscar el máximo" con for-each.
- Escribe el patrón "todas cumplen una condición" con for-each.
- Si necesitas el índice dentro de un bucle, ¿qué bucle usas? ¿Por qué no for-each?
Entrega: archivo cuestionario_seccion7.md con tus respuestas.
Criterios evaluados: CE 3.2, CE 3.7.
7.13 Lo que NO hemos visto (y dónde verlo)
Esta sección te ha enseñado el for-each para recorrer arrays sin índice. Hay varias cosas relacionadas que se reservan para secciones/unidades posteriores:
| Concepto | ¿Por qué no aquí? | ¿Dónde se ve? |
|---|---|---|
Colecciones (List, Set, Map) |
Necesita POO y genéricos. | UD6 (Tipos Avanzados de Datos). |
Iterable<T> y Iterator<T> |
Interfaces, genéricos y POO. | UD6. |
Genéricos (<T>, List<String>) |
Concepto avanzado de tipos parametrizados. | UD6. |
ConcurrentModificationException real |
Necesita colecciones para poder probarla. | UD6. |
break y continue para salir/saltar iteraciones |
Sentencias de salto de bucle. | Sección 8 de UD3. |
| Bucles anidados (for dentro de for, tablas, matrices) | Combinación de bucles. | Sección 8 de UD3. |
Matrices bidimensionales int[][] |
Arrays de arrays. | Sección 8 de UD3. |
| Streams API como alternativa a bucles | Forma declarativa de procesar colecciones. | UD6. |
Cuando llegues a UD6, el for-each será tu herramienta principal para recorrer colecciones. Por eso te lo enseñamos en UD3 con arrays: cuando llegues a UD6, ya lo tendrás interiorizado y solo tendrás que aprender las colecciones.
Cierre de la sección. Llegar hasta aquí es mérito. Llevas ya el for y el for-each en el cinturón, y encima has aprendido a manejar arrays. Eso es mucho: la mitad de la programación imperativa consiste en "recorrer una colección de cosas y hacer algo con cada una". La regla de oro —for-each lee, for clásico escribe— te va a ahorrar más bugs de los que crees. Y cuando llegues a UD6 y conozcas
List,Sety demás, el for-each será tu herramienta estrella para recorrerlas, porque ya lo habrás practicado a fondo con arrays. Nos vemos en la sección 8, donde cerramos el bloque de bucles con las sentencias de salto y los bucles anidados sobre matrices bidimensionales. Después, en la sección 9, aprenderás a manejar errores contry-catch-finally.