is there a Java equivalent to null coalescing operator (??) in C#? [duplicate]
Asked Answered
B

5

260

Is it possible to do something similar to the following code in Java

int y = x ?? -1;

More about ??

Bartie answered 7/3, 2011 at 17:35 Comment(8)
Voting to reopen as not a duplicate. This question is "Does x exist" the other question is "Since x doesn't exist how do I get y".De
On Java8+ has Optional class in jdk. Example of usage Optional.ofNullable(x).orElse(-1). Other good usage of usage Optional is method map. Let say there object a which is equivalent of json object: "a": {"b":{"c":1}}. To read c value can be such construction like: Optional.ofNullable(a).map(a->a.b).map(b->b.c).orElse(-1). Is much ugly literal syntax than C#, but it is better option that using cascading operator ?:Forget
This works in C# only if x is a nullable int. either Nullable<int> x; or int? x. if x is just int, its a compilation failure.Nonmetallic
Another one for my C# vs. Java list. Can't believe there's not even an Objects.coalesce(...) or equivalent.Helaina
@JoshM. There is indeed a coalesce equivalent from Java 9 onwards. Objects.requireNonNullElse and if you want short-circuiting behaviour there's Objects.requireNonNullElseGetChemosh
@Chemosh thank you. I looked at the API quickly and am sad to see that the defaultObj must be non-null. Also sad that it's named require... because it makes it sound like it's going to throw if the parameter is null, in reality it just returns the default object passed in. Poor naming. Should have been coalesce or similar.Helaina
@JoshM. Note that it does throw if the parameter is null and the default object/object supplier is also null.Absorber
@gt sure, just another example of Java's overzealous null handling. Really annoying.Helaina
E
202

Sadly - no. The closest you can do is:

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

Of course, you can wrap this up in library methods if you feel the need to (it's unlikely to cut down on length much), but at the syntax level there isn't anything more succinct available.

Elimination answered 7/3, 2011 at 17:36 Comment(7)
Which of course only works if x is an Integer because an int cannot be compared to null.Devour
@musiKk: and the C# equivalent would only work on int? (or rather any reference type or nullable)De
@De I am no C# developer so I have no idea.Devour
@musiKk: type? is how you declare a variable of a nullable type. The c# null coalescing operator only works on nullable or reference types. If the above example was C#, x would be of type int? -- but better written using the null coalescing operator as y=x?? -1;De
@De Oh, I thought that was a question......Devour
That's what code blocks are for so you can tell that int? is a data type, not a question. :)Hulsey
But x is evaluated twice (one for condition and one for assignation). When using null coalescing operator int y = x ?? -1, x is evaluated once.Renny
S
68

The Guava library has a method that does something similar called MoreObjects.firstNonNull(T,T).

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

This is more helpful when you have something like

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

since it saves you from either calling the potentially expensive method twice or declaring a local variable in your code to reference twice.

Stimulative answered 7/3, 2011 at 17:50 Comment(4)
Unfortunately this will throw a NullPointerException if all values are null. While coalesce can return null.Aldebaran
@Stefan: True, though I did say it was "similar" not exactly the same. And this sort of thing is by far the most useful for (and the most used for) cases where you want a fixed, non-null default if something is null. Given that, firstNonNull fails if the second argument is null to help programmer errors be caught faster.Stimulative
The real issue with a solution like this is that it sacrifices the null coalesces lazy evaluation. Since all of the values have to be passed to Objects.firstNonNull, any functions you have passed will be evaluated. This makes it potentially far more computationally expensive than C#'s ??.Mastoid
@AndrewCoonce: Sure, but there are a lot of use cases (like this example) where you just want a default or something that isn't expensive to compute. And when the alternative is expensive to compute, there's always the ternary.Stimulative
D
50

Short answer: no

The best you can do is to create a static utility method (so that it can be imported using import static syntax)

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

The above is equivalent to Guava's method firstNonNull by @ColinD, but that can be extended more in general

public static <T> T coalesce(T... params)
{
    for (T param : params)
        if (param != null)
            return param;
    return null;
}
Disharoon answered 23/7, 2015 at 12:44 Comment(2)
Please note that Guava's method throws exception if both parameters are null!Plutocracy
I get Possible heap pollution from parameterized vararg type warning when using the second one.Gwyngwyneth
F
36

ObjectUtils.firstNonNull(T...) from Apache Commons Lang 3 is another option. I prefer this because, unlike Guava, this method does not throw an Exception. It will simply return null.

Felicitasfelicitate answered 26/8, 2015 at 22:45 Comment(2)
this answer should be upvoted, as its most up to dateMarler
I love this! It cleans up so much of my code with annoying nested ternaries or drawn out if-else statements for assignments!Alexander
A
26

No, and be aware that workaround functions are not exactly the same, a true null coalescing operator short circuits like && and || do, meaning it will only attempt to evaluate the second expression if the first is null.

Albright answered 16/9, 2015 at 18:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.