How to get the first non-null value in Java?
Solution 1
No, there isn't.
The closest you can get is:
public static <T> T coalesce(T ...items) {
for(T i : items) if(i != null) return i;
return null;
}
For efficient reasons, you can handle the common cases as follows:
public static <T> T coalesce(T a, T b) {
return a == null ? b : a;
}
public static <T> T coalesce(T a, T b, T c) {
return a != null ? a : (b != null ? b : c);
}
public static <T> T coalesce(T a, T b, T c, T d) {
return ...
}
Solution 2
Apache Commons Lang 3
ObjectUtils.firstNonNull(T...)
Java 8 Stream
Stream.of(T...).filter(Objects::nonNull).findFirst().orElse(null)
Solution 3
If there are only two variables to check and you're using Guava, you can use MoreObjects.firstNonNull(T first, T second).
Solution 4
If there are only two references to test and you are using Java 8, you could use
Object o = null;
Object p = "p";
Object r = Optional.ofNullable( o ).orElse( p );
System.out.println( r ); // p
If you import static Optional the expression is not too bad.
Unfortunately your case with "several variables" is not possible with an Optional-method. Instead you could use:
Object o = null;
Object p = null;
Object q = "p";
Optional<Object> r = Stream.of( o, p, q ).filter( Objects::nonNull ).findFirst();
System.out.println( r.orElse(null) ); // p
Solution 5
Following on from LES2's answer, you can eliminate some repetition in the efficient version, by calling the overloaded function:
public static <T> T coalesce(T a, T b) {
return a != null ? a : b;
}
public static <T> T coalesce(T a, T b, T c) {
return a != null ? a : coalesce(b,c);
}
public static <T> T coalesce(T a, T b, T c, T d) {
return a != null ? a : coalesce(b,c,d);
}
public static <T> T coalesce(T a, T b, T c, T d, T e) {
return a != null ? a : coalesce(b,c,d,e);
}
Related videos on Youtube
froadie
Updated on December 17, 2021Comments
-
froadie over 2 years
Is there a Java equivalent of SQL's
COALESCE
function? That is, is there any way to return the first non-null value of several variables?e.g.
Double a = null; Double b = 4.4; Double c = null;
I want to somehow have a statement that will return the first non-null value of
a
,b
, andc
- in this case, it would returnb
, or 4.4. (Something like the sql method - returnCOALESCE(a,b,c)
). I know that I can do it explicitly with something like:return a != null ? a : (b != null ? b : c)
But I wondered if there was any built-in, accepted function to accomplish this.
-
Vishy about 14 yearsYou shouldn't need a function like this as you geneally wouldn't calculate 'c' if 'b' has the answer you want. i.e. you wouldn't build a list of possible answers only to keep one.
-
Adam Gent about 12 yearsCaveat: Not all RDBMS short circuit on COALESCE. Oracle only recently started doing it.
-
Dmitry Ginzburg about 9 years@BrainSlugs83 Seriously? Java should?
-
-
Bill K about 14 yearsGod I hate generics. I saw what yours meant right off the bat. I had to look at @LES2's twice to figure out that he was doing the same thing (and probably "better")! +1 for clarity
-
les2 about 14 yearsthe efficiency reasons that i mentioned above is that an array allocation will happen each time you invoke the var arg version of the method. this could be wasteful for hand-fulls of items, which i suspect will be common usage.
-
froadie about 14 yearsCool. Thanks. In that case I'll probably stick to the nested conditional operators in this case as it's the only time it has to be used and the user-defined method would be overkill...
-
Eric about 14 yearsYeah, generics are the way to go. But I'm not all that familiar with the intricacies.
-
les2 about 14 yearsI still would pull it out into a private helper method rather than leave a "scary looking" conditional block in the code - "what does that do?" that way, if you ever do need to use it again, you can use the refactoring tools in your IDE to move the method to the utility class. having the named method helps to document the intent of the code, which is always a good thing, IMO. (and the overhead of the non var-args version is probably barely measurable.)
-
Carl Manaster about 14 years+1 for pretty. Not sure about the efficiency benefits over the simple loop, but if you're going to eke out any tiny efficiency this way, it might as well be pretty.
-
Avi about 14 yearsTime to learn generics :-). There is little difference between @LES2's example and this, other than T instead of Object. -1 for building a function which will force casting the return value back to Double. Also for naming a Java method in all-caps, which may be fine in SQL, but isn't good style in Java.
-
Eric about 14 yearsI realize that all-caps is bad practice. I was just showing the OP how to write a function under the name they requested. Agreed, the cast back to
Double
is far from ideal. I just wasn't aware that static functions could be given type parameters. I thought it was just classes. -
les2 about 14 yearsthis way makes it much less painful and less error prone to write the overloaded variants!
-
Admin over 12 yearsObjects.firstNonNull only takes two arguments; there is no varargs equivalent in Guava. Also, it throws a NullPointerException if both args are null -- this may or may not be desirable.
-
Pang over 11 yearsWatch out: In
coalesce(a, b)
, ifb
is a complex expression anda
is notnull
,b
is still evaluated. This is not the case for the ?: conditional operator. See this answer. -
Ivan G. about 11 yearsthis requires every argument to be precalculated before the call to coalesce, pointless for performance reasons
-
les2 about 11 yearsyou should not use this function with expressions as there is no lazy evaluation in java ..... yet?
-
Michal Čizmazia almost 11 yearsHey, it does:
java.lang.NullPointerException: use Optional.orNull() instead of Optional.or(null)
-
Michal Čizmazia almost 11 yearsThis does the trick:
Optional.fromNullable(a).or(Optional.fromNullable(b)).orNull()
-
Anton Shchastnyi over 10 yearsGood comment, Jake. This NullPointerException often restricts Objects.firstNonNull usage. However, it's Guava's approach to avoid nulls at all.
-
quantum over 9 yearsNice article - it would be nice to have it English, though.
-
davidwebster48 over 9 yearsThat method is now deprecated, and the recommended alternative is MoreObjects.firstNonNull
-
HairOfTheDog about 9 yearsThere's something about that blog page that doesn't work with Google Translate. :-(
-
OrangeDog about 8 yearsIf NPE is undesired, then see this answer
-
Luke almost 8 yearsThe point of the efficient version was to not waste memory allocating an array by using
varargs
. Here, you're wasting memory by creating a stack frame for each nestedcoalesce()
call. Callingcoalesce(a, b, c, d, e)
creates up to 3 stack frames to calculate. -
Inego almost 5 yearsWhy wrap the first argument in a
Supplier
if it will be inspected anyway? For the sake of uniformity? -
kodlan almost 4 yearsI was looking for the same but for strings, and found out that there are SpringUtils.firstNonBlank(T...) and SpringUtils.firstNonBlank(T...) methods.
-
Vadzim over 3 yearsNote that both methods listed here introduce performance implications due to extra objects allocation, unlike simple ternary operator or Guava's
MoreObjects.firstNonNull
. -
Stephan Richter about 3 yearsPossible without the use of optional:
Object default = "some value"; Object res = ((res = getSomeNullable()) != null) ? res : default;
-
pyropunk51 about 3 years
Stream.of(null,"a")
will not work since theof
function is annotated with@NonNull
-
filpa over 2 yearsThis might be a bit old, but for completeness' sake: the approach by @Triqui does not necessarily evaluate all the parameters passed to
coalesce
- that's the point of the parameters being of typeSupplier
. They are evaluated only whenget()
is called - if the first parameter matches the criteria, the rest need not be evaluated. -
Mattwmaster58 over 2 yearsRequires Android 30