1. Expresiones vs sentencias
Todas las construcciones en Java se dividen en dos categorías: sentencias (Statement) y expresiones (Expression). De una sentencia se suele decir que se ejecuta, y de una expresión — que se evalúa. Pero eso no es lo principal.
La diferencia principal entre una sentencia y una expresión es que una expresión tiene un resultado de evaluación. Este resultado, en primer lugar, tiene un tipo, y en segundo lugar, se puede asignar en algún sitio o usar en otra expresión.
Ejemplos:
| Código | Notas |
|---|---|
|
Sentencia |
|
Expresión, tipo boolean |
|
Expresión; el tipo coincide con el de la variable i |
|
Expresión; el tipo coincide con el de la variable x |
¿Y qué nos aporta esto?
En primer lugar, podemos aprovechar el hecho de que muchas sentencias en realidad son expresiones (tienen un resultado). Por ejemplo, este código funcionará:
int x, y, z;
x = y = z = 1; // x = (y = (z = 1));
En segundo lugar, podemos ignorar el resultado de la evaluación de una expresión si queremos.
console.nextLine(); // ignoramos el resultado de la entrada
Ignorar el resultado de una expresión es útil, por ejemplo, si además de devolver un resultado también realiza alguna acción útil, y esa acción nos importa pero el resultado como tal — no.
2. Operador ternario
Este truco es más interesante que el anterior. En Java hay un operador especial ternario (triple). Se parece a una forma abreviada del operador if–else:
Condición ? Expresión1 : Expresión2;
Si la condición es verdadera, se evalúa expresión1; en caso contrario, se evalúa expresión2. Tras la condición va el signo de interrogación y las dos expresiones se separan con dos puntos.
La diferencia principal entre el operador ternario y el operador if-else es que el operador ternario es una expresión, por lo que su resultado se puede asignar a algo.
Por ejemplo, queremos calcular el mínimo de dos números. Usando el operador ternario, el código se vería así:
int a = 2;
int b = 3;
int min = a < b ? a : b;
O, supongamos, necesitas asignar a una variable distintos valores según una condición. ¿Cómo hacerlo?
Primera opción — usar el operador if-else:
int age = 25;
int money;
if (age > 30)
money = 100;
else
money = 50;
Segunda opción — usar el operador ternario, es decir, una forma abreviada de if-else:
int age = 25;
int money = age > 30 ? 100 : 50;
Entonces, ¿qué es mejor usar: if-else o el operador ternario? En cuanto a rendimiento, no hay mucha diferencia. Se trata más bien de legibilidad del código. Y esto es muy importante: el código no solo debe funcionar correctamente, sino también ser fácil de leer por otros programadores.
Un criterio sencillo puede ser este: si el código cabe en una sola línea, usa el operador ternario; si ya no cabe en una línea, es mejor usar if-else.
3. Matices de uso
Tipos de valores
Es importante recordar: ambas ramas del operador ternario (<valor_si_verdadero> y <valor_si_falso>) deben ser del mismo tipo o compatibles (por ejemplo, ambas String o ambas int).
Funciona:
int a = 10, b = 20;
int max = (a > b) ? a : b; // ambas ramas — int
Error de compilación:
int a = 10, b = 20;
// String e int no son compatibles
String result = (a > b) ? "mayor" : 0; // Error de compilación: no se puede asignar un int a una variable de tipo String
Opción correcta:
int a = 10, b = 20;
String result = (a > b) ? "mayor" : "menor o igual";
Ejemplo: trabajo con números
Calculemos el valor absoluto mediante el operador ternario:
int number = -5;
int abs = (number >= 0) ? number : -number;
System.out.println(abs); // 5
4. Integrar el operador ternario en una aplicación
Escribamos una pequeña aplicación de diálogo: además del saludo, el programa dirá al usuario cuántos años tendrá dentro de un año e indicará si será mayor de edad.
System.out.print("Introduce tu nombre: ");
String name = console.nextLine();
System.out.print("Introduce tu edad: ");
int age = console.nextInt();
int nextYear = age + 1;
String status = (nextYear >= 18) ? "mayor de edad" : "menor de edad";
System.out.println("Hola, " + name + "! El próximo año tendrás " + nextYear + ". Serás " + status + ".");
Expliquemos los detalles:
La variable status se calcula con el operador ternario: si la edad dentro de un año es al menos 18, el usuario será mayor de edad (o seguirá siéndolo).
5. Operadores ternarios anidados — ¡cuidado!
El operador ternario puede anidarse (en cada rama puede haber otro ternario). Pero… esto suele dar dolor de cabeza, especialmente a quien lea tu código después (incluso si eres tú dentro de 2 días).
Ejemplo: determinación de la categoría por edad
String category = (age < 7) ? "preescolar" :
(age < 18) ? "escolar" :
(age < 65) ? "adulto" : "jubilado";
Tabla de decisión:
| Edad | Condición | Resultado |
|---|---|---|
| < 7 | |
preescolar |
| 7–17 | |
escolar |
| 18–64 | |
adulto |
| 65 y más | en caso contrario | jubilado |
Este código aún se puede leer, pero si la lógica es más compleja — es mejor usar if-else if-else.
6. Truco: el operador ternario y el tipo boolean
A veces se escribe una expresión como:
boolean adult = (age >= 18) ? true : false;
Pero esto es redundante. La propia expresión (age >= 18) ya devuelve un boolean. Por lo tanto, se puede simplificar a:
boolean adult = (age >= 18);
GO TO FULL VERSION