¿Hay un equivalente de Java al operador coalescente nulo (??) en C#? [duplicate]

5 minutos de lectura

avatar de usuario
Nikita Ignacio

¿Es posible hacer algo similar al siguiente código en Java?

int y = x ?? -1;

Más sobre ??

  • Votar para reabrir como no un duplicado. Esta pregunta es “¿Existe x?”, la otra pregunta es “Ya que x no existe, ¿cómo obtengo y?”.

    – jmoreno

    17 de julio de 2015 a las 23:02

  • En Java8+ tiene una clase opcional en jdk. Ejemplo de uso Optional.ofNullable(x).orElse(-1). Otro buen uso del uso Opcional es el mapa de métodos. Digamos que hay un objeto a que es equivalente al objeto json: “a”: {“b”:{“c”:1}}. Para leer el valor c puede ser una construcción como: Optional.ofNullable(a).map(a->ab).map(b->bc).orElse(-1). ¿Es una sintaxis literal mucho más fea que C#, pero es una mejor opción que usar el operador en cascada?:

    – kikea

    13 de marzo de 2019 a las 19:46

  • Esto funciona en C# solo si x es un int anulable. cualquiera Nullable<int> x; o int? x. si x es solo int, es una falla de compilación.

    – Nombre en clave Jack

    12 oct 2020 a las 20:24


  • Otro para mi lista de C# vs. Java. No puedo creer que ni siquiera haya un Objects.coalesce(...) o equivalente.

    – josh m.

    30 de enero a las 17:29

Tristemente no. Lo más cercano que puedes hacer es:

int y = (x != null) ? x : -1;

Por supuesto, puede envolver esto en métodos de biblioteca si siente la necesidad de hacerlo (es poco probable que reduzca mucho la longitud), pero a nivel de sintaxis no hay nada más sucinto disponible.

  • Lo cual, por supuesto, solo funciona si x es un Integer porque un int no se puede comparar con null.

    – músicaKk

    7 de marzo de 2011 a las 17:38


  • @musiKk: ¿y el equivalente de C# solo funcionaría en int? (o más bien cualquier tipo de referencia o anulable)

    – jmoreno

    17 de julio de 2015 a las 23:08

  • @musiKk: tipo? es cómo declaras una variable de un tipo anulable. El operador coalescente nulo de c# solo funciona en tipos anulables o de referencia. Si el ejemplo anterior fuera C#, ¿x sería de tipo int? — pero mejor escrito usando el operador coalescente nulo como y=x?? -1;

    – jmoreno

    18 de julio de 2015 a las 15:17

  • @jmoreno Oh, pensé que era una pregunta…

    – músicaKk

    18 de julio de 2015 a las 15:18

  • eso es lo que code blocks son para que puedas decir eso int? es un tipo de dato, no una pregunta. 🙂

    – ErikE

    16 de septiembre de 2018 a las 2:09

avatar de usuario
colind

Guayaba tiene un método que hace algo similar llamado MásObjetos.firstNonNull(T,T).

Integer x = ...
int y = MoreObjects.firstNonNull(x, -1);

Esto es más útil cuando tienes algo como

int y = firstNonNull(calculateNullableValue(), -1);

ya que le evita llamar dos veces al método potencialmente costoso o declarar una variable local en su código para hacer referencia dos veces.

  • Desafortunadamente, esto generará una NullPointerException si todos los valores son nulos. Mientras que coalesce puede devolver nulo.

    – Stefan

    25/01/2014 a las 18:00

  • @Stefan: Cierto, aunque dije que era “similar”, no exactamente lo mismo. Y este tipo de cosas es, con mucho, la más útil (y la más utilizada) para los casos en los que desea un valor predeterminado fijo y no nulo si algo es nulo. Dado que, firstNonNull falla si el segundo argumento es nulo para ayudar a que los errores del programador se detecten más rápido.

    – ColinD

    27 de enero de 2014 a las 18:37

  • El problema real con una solución como esta es que sacrifica la evaluación perezosa nula coalesce. Dado que todos los valores tienen que ser pasados ​​a Objects.firstNonNull, cualquier función que haya aprobado será evaluada. Esto lo hace potencialmente mucho más costoso desde el punto de vista computacional que el de C#. ??.

    – Andrew Coonce

    27/10/2014 a las 17:30

  • @AndrewCoonce: Claro, pero hay muchos casos de uso (como este ejemplo) en los que solo desea un valor predeterminado o algo que no sea costoso de calcular. Y cuando la alternativa es costosa de calcular, siempre está el ternario.

    – ColinD

    27/10/2014 a las 17:39

avatar de usuario
usr-local-ΕΨΗΕΛΩΝ

Respuesta corta: no

Lo mejor que puede hacer es crear un método de utilidad estático (para que pueda importarse usando import static sintaxis)

public static <T> T coalesce(T one, T two)
{
    return one != null ? one : two;
}

Lo anterior es equivalente al método de guayaba. firstNonNull por @ColinD, pero eso se puede extender más en general

public static <T> T coalesce(T... params)
{
    for (T param : params)
        if (param != null)
            return param;
    return null;
}

  • No hablé de C#, hablé del lenguaje Swift y su encadenamiento opcional.

    – Pasha

    10 de febrero de 2017 a las 22:11

  • ¡Tenga en cuenta que el método de Guava arroja una excepción si ambos parámetros son nulos!

    – Nace

    11 de septiembre de 2018 a las 10:22

No, y tenga en cuenta que las funciones alternativas no son exactamente las mismas, un verdadero operador coalescente nulo cortocircuita como && y || do, lo que significa que solo intentará evaluar la segunda expresión si la primera es nula.

ObjectUtils.firstNonNull(T...), de Apache Commons Lang 3 es otra opción. Prefiero esto porque a diferencia de Guayaba, este método no arroja un Exception. simplemente regresará null;

  • esta respuesta debe ser votada, ya que es la más actualizada

    – mattsmith5

    7 de septiembre de 2021 a las 3:53

  • ¡Me encanta esto! Limpia gran parte de mi código con ternarios anidados molestos o declaraciones if-else extraídas para tareas.

    – casa de baños

    9 oct 2021 a las 19:02

Las primitivas en Java nunca pueden ser nulas, por lo que esa declaración no tiene sentido conceptualmente. Sin embargo, las clases contenedoras (entero, carácter, etc.), así como cualquier otra clase instanciable, pueden ser nulas.

Además de ese hecho, no hay ninguna sintaxis abreviada para un operador de fusión nulo. Debe utilizar la forma expandida.

  • esta respuesta debe ser votada, ya que es la más actualizada

    – mattsmith5

    7 de septiembre de 2021 a las 3:53

  • ¡Me encanta esto! Limpia gran parte de mi código con ternarios anidados molestos o declaraciones if-else extraídas para tareas.

    – casa de baños

    9 oct 2021 a las 19:02

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad