Documentos de Académico
Documentos de Profesional
Documentos de Cultura
PR UD2 – Tema 1
Dos de las más esenciales son las alterativas y las repetitivas, también denominadas
estructuras de control, ya que modifican o controlan el flujo normal del programa.
2. Operadores
Tal como se vio anteriormente, existen varios tipos de operadores y, en cuestión de las
estructuras de control, los esenciales son los relacionales y los lógicos.
En este caso, devolverá true si la variable de tipo char letr contiene la letra C.
En este caso, devolverá true si la variable de tipo int num1 NO contiene el valor 5.
Cuantitativos: Estos operadores evalúan si un número es mayor ‘>’, menor ‘<’, mayor o igual
‘>=’ o menor o igual ‘<=’ a otro número.
En este ejemplo, la primera línea devuelve true si el valor de la variable de tipo int num1 es
mayor que 8. En el segundo caso, devolverá true si el valor de la variable num2 es menor o
igual al de la variable num3.
Hay que tener en cuenta que, en Java, un carácter puede ser transformado en un entero, ya
que cada uno tiene asignado un valor número en la tabla UNICODE, por lo que pueden ser
comparados cuantitativamente. En este sentido, por orden alfabético, la letra ‘a’ será menor
que la letra ‘b’ y la letra ‘A’ será menor que la ‘z’, ya que las mayúsculas van antes de las
minúsculas.
2.2. Operadores condicionales o lógicos
Los operadores condicionales o lógicos son los que evalúan valores booleanos entre sí.
Este tipo de operador permiten unir varias expresiones relacionales para realizar una condición
mayor.
AND: Más comúnmente ‘&&’. Evalúa que ambas expresiones son ciertas.
En este caso, devolverá true si la variable de tipo int num1 es mayor que 5 y es menor que 10.
OR: Más comúnmente ‘||’. Evalúa que alguna de las expresiones es cierta.
En este ejemplo, devolverá true si la variable de tipo char ltr contiene un carácter ‘A’ o ‘X’.
En este caso, invierte el valor interior, devolviendo true si la variable de tipo char ltr no
contiene el carácter ‘A’ ni ‘X’.
A nivel de condición, lo que hay que tener en cuenta es que, los dobles evalúan elemento a
elemento y si alguno cumple o incumple la condición, deja de leer, evitando posibles errores.
En este ejemplo, si num1 es menor que 5, ya no evalúa la siguiente parte, puesto que el
resultado será false automáticamente.
En este otro caso, si la variable ltr contiene el valor ‘A’, ya no sigue evaluando, ya que
automáticamente será true.
En este ejemplo, ambas expresiones son equivalentes, devolviendo el mismo resultado en las
mismas condiciones.
En este otro ejemplo sucede lo mismo. Hay que prestar especial atención a los operadores y
sus inversas.
3.1. If
La sentencia if es la más sencilla, pues agrupa un conjunto de instrucciones que se ejecutan si
se cumple la condición establecida. En caso de que dicha condición no se cumpla, no hará
nada, y el programa seguirá tras el bloque de código.
En este caso, se mostrará el mensaje por pantalla si la variable de tipo int nota es igual o
mayor que 5.
3.1.1. Else
Con else se puede complementar el if, de tal forma que, si no se cumple la condición, se
realizan otras operaciones distintas.
En este caso, si la variable de tipo int nota es mayor que cinco, se comprueba si es igual a diez
y mostrará un mensaje u otro dependiendo de si cumple esa condición o no. En caso de que
sea menor que 5, verificará si es igual a 0 y mostrará un mensaje u otro dependiendo de esa
condición.
Para abreviar, el else con un if en su interior se puede establecer mediante else if.
Este ejemplo es el mismo que el anterior, solo que con el else más compacto. Ambas
aproximaciones son igual de válidas, aunque hay un debate de qué resulta más legible.
3.2. Switch
La instrucción switch es una sentencia condicional múltiple, permite establecer múltiples
valores posibles para una expresión y actuar en consecuencia para cada uno de ellos.
La expresión o variable a evaluar se pone junto al switch, mientras que cada opción de valor se
establece con un case en el interior del switch.
Como puede observarse, dependiendo del valor de la variable tipo char letra, se efectuarán
unas operaciones u otras. En este caso, si establecen tres casos, si vale ‘a’, si vale ‘b’ o,
mediante el uso del default, si no cumple nada de lo anterior.
Las instrucciones switch son muy versátiles en sus opciones y ejecutarán línea a línea todo lo
que va desde el case que cumple hasta que se encuentra un break o termina el switch.
En este caso, si la variable de tipo String sistema tiene el valor “Linux” o “Ubuntu”, mostrará lo
mismo por pantalla, puesto que no hay un break que lo pare.
En este otro ejemplo, puede verse que se pueden realizar operaciones y continuar realizando
otras dependiendo de la condición.
En este caso, una persona tiene nombre, apellidos y edad, y un animal nombre y edad, por lo
que, se puede aprovechar el switch de tal forma que se tengan que repetir varias veces los
mensajes.
Su escritura es sencilla, se pone la condición entre ‘()’, el signo de interrogación ‘?’, el resultado
en caso de que se cumpla la condición, los dos puntos ‘:’ y el resultado en caso de que no se
cumpla.
Como puede observarse, este operador permite realizar operaciones de forma más sencilla,
como la asignación o la muestra de datos por pantalla, entre otras muchas cosas.
Existen varios tipos de bucles, cada uno con sus características y enfocados a un tipo de
operación, pero todo bucle tiene un inicio y un fin establecidos mediante una condición.
Este bucle está formado por tres secciones pre-bucle, condición y post-bucle separadas por
punto y coma ‘;’. Estas secciones se suelen utilizar para la variable auxiliar, la condición y la
modificación del valor en cada iteración.
Las tres son opcionales, pero ha de respetarse su posición, funcionalidad y siempre aparecer el
punto y coma, esté o no dicha sección.
4.1.1. Variable auxiliar. Pre-bucle
La primera sección del bucle suele ser la creación e inicialización de variable auxiliar. Esta se
crea y se inicializa directamente en la sección, por lo que su ámbito solo es el propio bucle.
4.1.2. Condición
La condición establece si se realiza otra iteración o no, evaluándose antes de realizar cada
iteración, incluyendo la primera. Mientras esta sea cierta, el bucle continuará.
En este caso, se utiliza el bucle para mostrar por pantalla el valor de cada elemento del array.
Como puede observarse, se ha utilizado el atributo length para saber cuándo parar. Dado que
la longitud es el número de elementos, esta siempre es un número más que la última posición
del array, por lo que se compara con menor que y no menor o igual.
Su sintaxis es sencilla, tan solo la palabra reservada while seguido de la expresión a evaluar
entre paréntesis.
En este caso, es necesario realizar algo en el bucle que cambie el valor de esa condición para
que pare.
4.3. Hacer mientras. Do-while
El bucle do-while es similar al while, con la salvedad de que primero se ejecuta cada la
iteración y luego se evalúa la condición.
En este caso, la sintaxis está invertida, primero la palabra reservada do y al final, while y la
condición.
En este caso, aunque la variable que establece la condición es falsa, se realiza la primera
iteración del bucle igualmente, ya que esta se evalúa al final.
El bucle for each está diseñado para recorridos de lectura, en los que no importan índices ni
posiciones.
Su sintaxis tiene una forma fija, primero la palabra reservada for, luego una variable auxiliar
del mismo tipo que el tipo de la colección, luego dos puntos ‘:’ y luego la colección a recorrer.
En este ejemplo, se utiliza el bucle para recorrer un array de caracteres, concatenarlos en una
variable de tipo String y así formar la palabra “hola”.
Esto es costoso para el sistema y solo ha de hacerse si el coste de no hacerlo es mucho mayor.
4.5.1. Break
Para terminar el bucle se utiliza el break, el cual rompe el bucle actual, como si la condición no
se cumpliese.
En este ejemplo, se busca un número en concreto entre 50 mil y, una vez encontrado, se
realizan las operaciones oportunas y se rompe el bucle. Esto se hace porque solo se necesita
ese dato en concreto y continuar con la ejecución es una pérdida de tiempo y recursos.
Hay que tener en cuenta que, si hay bucles anidados, solo cierra el actual, no toda la cadena.
4.5.2. Return
Un return en un método termina el método directamente una vez se encuentra, por lo que
puede utilizarse para terminar la ejecución de una operación bajo una circunstancia.
En este ejemplo, se busca un número en un array y, una vez encontrado, se lanza el return,
cortando todo el método.
El uso de un return para terminar una ejecución es mucho más eficiente que el uso de un
break, por lo que, suele ser preferible pasar la lógica a un método y romperla mediante un
return.
En este caso, si la condición del if se cumple, el continue hará que salte a la siguiente iteración
sin mostrar el mensaje por pantalla ni lo que pudiese estar después.
Por esto, es de vital importancia detectarlos mientras se crea y prueba el código, ya que
podrían echar abajo todo un sistema. Luego, habría que analizar todo el código del programa,
buscar el fallo y corregirlo, cosa que puede llevar tiempo durante el cual el sistema no
funcione.
En este caso, hay que tener en cuenta que las variables auxiliares tienen que tener nombres
distintos, puesto que comparten ámbito del bucle externo.
Como los internos están dentro de los anteriores, tienen acceso a todo lo creado
anteriormente.
Cada iteración del bucle externo se realiza cuando se realizan todas las del interno.
En este ejemplo, se utilizan dos bucles for para recorrer una matriz, de tal forma que el primer
bucle recorre cada array de la matriz y el segundo, cada elemento de cada array.
Como puede observarse, la variable auxiliar interna, por estándar de facto, se denomina
siguiendo el alfabeto, aunque puede establecerse un nombre significativo.
5. Recursividad
La recursividad es el proceso por el cual un método se llama a sí mismo para realizar su misma
operación en un subconjunto de datos.
Estos métodos suelen ser cortos, de pocas líneas y siguiendo una misma estructura, un if con
una condición que parará la recursividad con un return (caso base) y en el else, la operación
recursiva realizada en un return.
En este ejemplo, el método devuelve un String con los num primeros números pares.
Las operaciones en las que compensa son recorridos de ciertas estructuras, búsquedas,
ordenaciones y operaciones matemáticas. Normalmente, estas operaciones suelen ser muy
complejas de realizar mediante bucles y extremadamente simples de forma recursiva.
Hay que tener en cuenta que la llamada recursiva debe ser lo último a realizar, debe estar
dentro del return para que su coste sea menor, pues así están diseñado proceso.
Dado que todo el método va a repetirse una y otra vez y almacenarse en memoria, es de vital
importancia no crear nada en su interior, ni siquiera variables, o el coste será exponencial.
Esto puede suceder por dos razones, o bien el proceso recursivo no está correctamente
confeccionado y nunca termina, o este proceso es demasiado extenso y la máquina virtual de
Java no dispone de suficiente memoria para realizarlo.