tabbedpane sirve settitle que personalizar para name how java nullable optional

sirve - tabbed java



¿Cómo volver cuando un opcional está vacío? (5)

El ifPresent que está usando no requiere que cree un nuevo lambda, solo puede usar una referencia de método:

getOptional().ifPresent(System.out::println);

Sin embargo, esto realmente no resuelve el caso en el que desea condicionar la presencia de dos opcionales. Pero como alternativa a

// And want to return if it''s empty if (!o.isPresent()) return;

¿por qué no simplemente revertir la condición, que también funciona bien en el caso anidado? No hay necesidad de hacer explícita la devolución:

if (o.isPresent()) { System.out.println(o.get()); if (oo.isPresent()) { System.out.println(oo.get()); } }

Sin embargo, este tipo de caso de uso sugiere que realmente no se está beneficiando de Opcional en lugar de un valor anulable. En general, si está usando isPresent y get, entonces es posible que Opcional no le esté obteniendo mucho (excepto que lo obliga a considerar el caso en el que falta el valor). El uso de ifPresent, el mapa, el filtro y otros métodos "más funcionales" podrían ser usos más típicos de un valor opcional.

Pero en cualquier caso, no devuelva el valor nulo cuando prometa un opcional. Si bien es perfectamente legal devolver el valor nulo cuando se espera un objeto, el punto de Opcional es precisamente evitar tener que verificar el valor nulo. Así que no hagas:

Optional<String> getOptional() { return null; }

pero en su lugar haz:

Optional<String> getOptional() { return Optional.empty(); }

De lo contrario acabas teniendo que hacer:

Optional<String> o = getOptional(); if (o != null && o.isPresent()) { // ... }

que en realidad es hacer el mismo tipo de cosas dos veces. Use un opcional, o use un valor que pueda contener nulos, ¡pero no haga ambas cosas!

Me encanta que los optionals están ahora en la biblioteca estándar de Java. Pero hay un problema básico con el que me encuentro y que no he descubierto cómo resolverlo de la mejor manera (la más fácil de leer y entender, la más bonita, la más corta):

¿Cómo volver de un método cuando un opcional está vacío?

Estoy buscando una solución general que funcione para diferentes combinaciones de números de opcionales y tamaños de bloques de código.

En los siguientes ejemplos intentaré mostrar lo que quiero decir:

void m1() { // When I get an optional: Optional<String> o = getOptional(); // And want to return if it''s empty if (!o.isPresent()) return; // In the whole rest of the method I have to call Optional.get // every time I want the value: System.out.println(o.get()); // Which is pretty ugly and verbose! } void m2() { // If I instead return null if a value is absent: String s = getNullabe(); if (s == null) return; // Then I can use the value directly: System.out.println(s); }

Esta pregunta trata sobre cómo obtener el buen aspecto de los dos ejemplos anteriores: el tipo seguro del opcional y la brevedad de los tipos anulables.

El resto de los ejemplos ilustran esto más.

void m3() { // If I on the other hand want to throw on empty that''s pretty and compact: String s = getOptional() .orElseThrow(IllegalStateException::new); System.out.println(s); } void m4() { Optional<String> o = getOptional(); if (!o.isPresent()) return; // I can of course declare a new variable for the un-optionalised string: String s = o.get(); System.out.println(s); // But the old variable still remains in scope for the whole method // which is ugly and annoying. System.out.println(o.get()); } void m5() { // This is compact and maybe pretty in some ways: getOptional().ifPresent(s -> { System.out.println(s); // But the extra level of nesting is annoying and it feels // wrong to write all the code in a big lambda. getOtherOptional().ifPresent(i -> { // Also, more optional values makes it really weird and // pretty hard to read, while with nullables I would // get no extra nesting, it would looks good and be // easy to read. System.out.println("i: " + i); // It doesn''t work in all cases either way. }); }); } Optional<String> getOptional() { throw new UnsupportedOperationException(); } Optional<Integer> getOtherOptional() { throw new UnsupportedOperationException(); } String getNullabe() { throw new UnsupportedOperationException(); }

¿Cómo puedo regresar de un método si un opcional está vacío, sin tener que usar get en el resto del método, sin declarar una variable adicional y sin niveles adicionales de anidamiento de bloques?

O si no es posible obtener todo eso, ¿cuál es la mejor manera de manejar esta situación?


En su lugar, puede usar map métodos ifPresent y map , si la función es nula y necesita hacer efectos secundarios, puede usar ifPresent ,

optional.ifPresent(System.out::println);

Si la devolución de otro método se basa en la Opcional, entonces ese método podría necesitar devolver también una Opcional y utilizar el método de mapa

Optional<Integer> getLength(){ Optional<String> hi = Optional.of("hi"); return hi.map(String::length) }

La mayoría de las veces, cuando llama a " isPresent y get , está haciendo un mal uso de " Optional .


Ese es un gran tema, a todos nos encanta el estilo funcional de programación.

A menudo, cuando se inicia una implementación de un método, se le da un derecho opcional en la parte superior. En este punto, comienza a preguntarse qué es lo mejor que puede hacer para manejar un opcional vacío, solo tiene sentido salir y detener el procesamiento si ese es el caso.

PASO 1 - Explorar y anylyze

public void processMedia(String mediaClassName, String mediaName) { // THAT MIGHT BE YOUR FIRST IDEA MediaClass mediaClass = mediaClassFinder.find(mediaClassName).orElse(null); // RETURNING ON NULL CONDITION LIKE THE BELOW CAN BE ALRIGHT, // BUT POSSIBLY YOU CAN DO BETTER if (mediaClass == null) { return; } Optional<Media> media = mediaFinder.find(mediaClass.getId(), mediaName); // do processing // render the processed object }

PASO 2 El mejor enfoque podría ser extraer varias partes de la implementación a métodos separados y encadenarlos en un estilo funcional. Como efecto secundario de este ejercicio, es probable que termine con una interfaz y una estructura muy mejoradas de su aplicación. Así es como funciona la refactorización. Mire a continuación, no hay asignaciones nulas explícitas ni puntos de retorno adicionales en ninguna parte. Y la codificación se convierte en diversión.

public void processMedia(String mediaClassName, String mediaName) { mediaClassFinder.find(mediaClassName) .flatMap(mediaClass -> mediaFinder.find(mediaClass.getId(), mediaName)) .map(this::compress) .ifPresent(this::render); } private Media compress(Media media) { // compress media implementation return media; } private void render(Media media) { // render media implementation }

Espero que te haya gustado mi ejemplo :)


No creo que lo que estás preguntando sea realmente posible, pero me gustaría sugerir que solo tomes todo el código que funciona directamente en tu String y lo envuelvan en una función. Entonces tu función se convierte en algo como esto:

void m4() { Optional<String> o = getOptional(); if (!o.isPresent()) return; doThings(o.get()); } void doThings(String s){ System.out.println(s); //do whatever else with the string. }

De esta manera, solo tiene el alcance de la Cadena y no tiene que llamar a .get() cada vez que quiera acceder a ella.


Podrías usar orElse(null) :

String o = getOptional().orElse(null); if (o == null) { return; }