Su error principal es que todavía está pensando en términos más de procedimiento. Esto no es una crítica de usted como persona, es simplemente una observación. Pensar en términos más funcionales viene con tiempo y práctica, y por lo tanto, los métodos son: Presente y consiga el aspecto más obvio y correcto para usted. Tu segundo error secundario es crear tu Opcional dentro de tu método. La Opcional pretende ayudar a documentar que algo puede o no devolver un valor. Puede que no consigas nada.
Esto te ha llevado a escribir un código perfectamente legible que parece perfectamente razonable, pero fuiste seducido por las viles tentadoras gemelas que se ponen y están presentes.
Por supuesto, la pregunta se convierte rápidamente en "¿por qué están presentes e incluso están ahí?"
Una cosa que mucha gente se pierde es que el Presente () es que no es algo que esté hecho para un nuevo código escrito por personas totalmente a bordo con cuánta lambda útil son las gambas, ya quién le gusta lo funcional.
Sin embargo, nos brinda algunos (dos) beneficios buenos, excelentes, glamorosos (?):
- Facilita la transición del código heredado para usar las nuevas funciones.
- Facilita las curvas de aprendizaje de Opcional.
El primero es bastante simple.
Imagina que tienes una API que se parece a esto:
public interface SnickersCounter {
/**
* Provides a proper count of how many snickers have been consumed in total.
*/
public SnickersCount howManySnickersHaveBeenEaten();
/**
* returns the last snickers eaten.<br>
* If no snickers have been eaten null is returned for contrived reasons.
*/
public Snickers lastConsumedSnickers();
}
Y tenías una clase heredada usando esto como tal (rellena los espacios en blanco):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
Un ejemplo artificial para estar seguro. Pero ten paciencia conmigo aquí.
Java 8 se ha iniciado y estamos luchando para subir a bordo.
Entonces, una de las cosas que hacemos es que queremos reemplazar nuestra interfaz anterior con algo que devuelve Opcional.
¿Por qué?
Porque como alguien más ya ha mencionado gentilmente:
Esto elimina las conjeturas de si algo puede ser nulo
Esto ya ha sido señalado por otros. Pero ahora tenemos un problema. Imagínese que tenemos (perdóneme mientras presiono alt + F7 en un método inocente), 46 lugares donde este método se llama en un código legado bien probado que, de lo contrario, hace un excelente trabajo. Ahora tienes que actualizar todos estos.
ESTO es donde brilla el presente.
Porque ahora:
Snickers lastSnickers = snickersCounter.lastConsumedSnickers ();
if (null == lastSnickers) {
lanzar nuevo NoSuchSnickersException ();
}
else {
consumer.giveDiabetes (lastSnickers);
}
se convierte en:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
Y este es un cambio simple que puedes darle al nuevo junior: él puede hacer algo útil, y podrá explorar el código base al mismo tiempo. ganar-ganar Después de todo, algo parecido a este patrón está bastante extendido. Y ahora no tiene que volver a escribir el código para usar lambdas o algo así.
(En este caso particular, sería trivial, pero dejo algunos ejemplos en los que sería difícil como ejercicio para el lector).
Tenga en cuenta que esto significa que la forma en que lo hizo es esencialmente una forma de lidiar con el código heredado sin hacer reescrituras costosas. Entonces, ¿qué pasa con el nuevo código?
Bueno, en tu caso, donde solo quieres imprimir algo, simplemente lo harías:
snickersCounter.lastConsumedSnickers (). ifPresent (System.out :: println);
Que es bastante simple, y perfectamente claro.
El punto que está saliendo lentamente hacia la superficie es que existen casos de uso para get () y isPresent (). Están ahí para permitirle modificar el código existente mecánicamente para usar los tipos más nuevos sin pensar demasiado en ello.
Por lo tanto, lo que estás haciendo está mal orientado de las siguientes maneras:
- Estás llamando a un método que puede devolver nulo. La idea correcta sería que el método devuelve nulo.
- Estás usando los métodos heredados de banda para lidiar con este opcional, en lugar de usar los nuevos y sabrosos métodos que contienen la fantasía lambda.
Si desea utilizar Opcional como una simple comprobación de seguridad nula, lo que debería haber hecho es simplemente esto:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
Por supuesto, la buena versión de este se ve así:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
Por cierto, aunque no es obligatorio, recomiendo usar una nueva línea por operación, para que sea más fácil de leer.
Fácil de leer y comprender los tiempos de concisión cualquier día de la semana.
Este es, por supuesto, un ejemplo muy simple donde es fácil entender todo lo que estamos tratando de hacer. No siempre es así de simple en la vida real. Pero note cómo en este ejemplo, lo que expresamos son nuestras intenciones. Queremos OBTENER al empleado, OBTENER su identificación y, si es posible, imprimirlo. Esta es la segunda gran victoria con Opcional. Nos permite crear código más claro. También creo que hacer cosas como hacer un método que haga un montón de cosas para que puedas incluirlo en un mapa es, en general, una buena idea.