197

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, and c - in this case, it would return b, or 4.4. (Something like the sql method - return COALESCE(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.

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
froadie
  • 79,995
  • 75
  • 166
  • 235
  • 3
    You 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. – Peter Lawrey May 06 '10 at 21:26
  • Caveat: Not all RDBMS short circuit on COALESCE. Oracle only recently started doing it. – Adam Gent Apr 30 '12 at 19:41

13 Answers13

289

Apache Commons Lang 3

ObjectUtils.firstNonNull(T...)

Java 8 Stream

Stream.of(T...).filter(Objects::nonNull).findFirst().orElse(null)

Andrzej Polis
  • 3,205
  • 2
  • 14
  • 10
  • 3
    I was looking for the same but for strings, and found out that there are SpringUtils.firstNonBlank(T...) and SpringUtils.firstNonBlank(T...) methods. – kodlan Jul 29 '20 at 17:23
  • 2
    Note that both methods listed here introduce performance implications due to extra objects allocation, unlike simple ternary operator or Guava's `MoreObjects.firstNonNull`. – Vadzim Nov 10 '20 at 08:51
  • 1
    `Stream.of(null,"a")` will not work since the `of` function is annotated with `@NonNull` – pyropunk51 Jul 08 '21 at 07:02
  • @pyropunk51 it's only `Stream.of(null)` which throws a null pointer exception. With more than one arguments any argument can be `null`, at least since Java 11. – Volker Seibt Mar 27 '23 at 13:22
130

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 ...
}

The efficiency reason is that an array allocation will happen each time you invoke the ... version of the method. This could be wasteful for hand-fulls of items, which I suspect will be common usage.

Dmitriy Popov
  • 2,150
  • 3
  • 25
  • 34
les2
  • 14,093
  • 16
  • 59
  • 76
  • 4
    the 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. – les2 May 04 '10 at 18:54
  • Cool. 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... – froadie May 04 '10 at 18:55
  • 8
    I 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.) – les2 May 04 '10 at 19:07
  • 13
    Watch out: In `coalesce(a, b)`, if `b` is a complex expression and `a` is not `null`, `b` is still evaluated. This is not the case for the ?: conditional operator. See [this answer](http://stackoverflow.com/a/978357/1402846). – Pang Dec 26 '12 at 09:48
  • 1
    this requires every argument to be precalculated before the call to coalesce, pointless for performance reasons – Ivan G. Jun 20 '13 at 09:07
  • you should not use this function with expressions as there is no lazy evaluation in java ..... yet? – les2 Jun 24 '13 at 23:20
  • Hoping to be useful I integrated the comment from les2 in their answer itself – Valerio Bozz Aug 08 '23 at 13:15
67

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
fabian
  • 80,457
  • 12
  • 86
  • 114
Christian Ullenboom
  • 1,388
  • 3
  • 24
  • 20
  • Possible without the use of optional: `Object default = "some value"; Object res = ((res = getSomeNullable()) != null) ? res : default; ` – Stephan Richter May 04 '21 at 09:35
66

If there are only two variables to check and you're using Guava, you can use MoreObjects.firstNonNull(T first, T second).

Kellen Donohue
  • 777
  • 8
  • 17
Dave
  • 5,133
  • 21
  • 27
  • 58
    Objects.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. –  Dec 23 '11 at 21:25
  • 2
    Good comment, Jake. This NullPointerException often restricts Objects.firstNonNull usage. However, it's Guava's approach to avoid nulls at all. – Anton Shchastnyi Jan 10 '14 at 14:22
  • 4
    That method is now deprecated, and the recommended alternative is [MoreObjects.firstNonNull](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/MoreObjects.html#firstNonNull(T,%20T)) – davidwebster48 Feb 17 '15 at 00:58
  • 1
    If NPE is undesired, then see [this answer](http://stackoverflow.com/a/18741740/476716) – OrangeDog Jun 09 '16 at 10:11
26

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);
}
Eric
  • 95,302
  • 53
  • 242
  • 374
  • 5
    +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. – Carl Manaster May 04 '10 at 19:08
  • 3
    this way makes it much less painful and less error prone to write the overloaded variants! – les2 May 10 '10 at 18:45
  • 3
    The 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 nested `coalesce()` call. Calling `coalesce(a, b, c, d, e)` creates up to 3 stack frames to calculate. – Luke Sep 23 '16 at 00:20
  • Overloading hell – Lluis Martinez Jun 01 '23 at 11:16
12

This situation calls for some preprocessor. Because if you write a function (static method) which picks the first not null value, it evaluates all items. It is problem if some items are method calls (may be time expensive method calls). And this methods are called even if any item before them is not null.

Some function like this

public static <T> T coalesce(T ...items) …

should be used but before compiling into byte code there should be a preprocessor which find usages of this „coalesce function“ and replaces it with construction like

a != null ? a : (b != null ? b : c)

Update 2014-09-02:

Thanks to Java 8 and Lambdas there is possibility to have true coalesce in Java! Including the crucial feature: particular expressions are evaluated only when needed – if earlier one is not null, then following ones are not evaluated (methods are not called, computation or disk/network operations are not done).

I wrote an article about it Java 8: coalesce – hledáme neNULLové hodnoty – (written in Czech, but I hope that code examples are understandable for everyone).

Franta
  • 7,547
  • 1
  • 17
  • 8
7

You can try this:

public static <T> T coalesce(T... t) {
    return Stream.of(t).filter(Objects::nonNull).findFirst().orElse(null);
}

Based on this response

Lucas León
  • 602
  • 1
  • 7
  • 11
6

Since Java 9 there is builtin Objects.requireNonNullElse method for two parameter coalesce. That was the most useful for me.

Mert Ülkgün
  • 124
  • 1
  • 7
5

With Guava you can do:

Optional.fromNullable(a).or(b);

which doesn't throw NPE if both a and b are null.

EDIT: I was wrong, it does throw NPE. The correct way as commented by Michal Čizmazia is:

Optional.fromNullable(a).or(Optional.fromNullable(b)).orNull();
Jamol
  • 2,281
  • 2
  • 28
  • 28
5

How about using suppliers when you want to avoid evaluating some expensive method?

Like this:

public static <T> T coalesce(Supplier<T>... items) {
for (Supplier<T> item : items) {
    T value = item.get();
    if (value != null) {
        return value;
    }
    return null;
}

And then using it like this:

Double amount = coalesce(order::firstAmount, order::secondAmount, order::thirdAmount)

You can also use overloaded methods for the calls with two, three or four arguments.

In addition, you could also use streams with something like this:

public static <T> T coalesce2(Supplier<T>... s) {
    return Arrays.stream(s).map(Supplier::get).filter(Objects::nonNull).findFirst().orElse(null);
}
Stephen King
  • 581
  • 5
  • 18
  • 31
Triqui
  • 51
  • 1
  • 1
  • Why wrap the first argument in a `Supplier` if it will be inspected anyway? For the sake of uniformity? – Inego Sep 20 '19 at 09:14
  • 1
    This 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 type `Supplier`. They are evaluated only when `get()` is called - if the first parameter matches the criteria, the rest need not be evaluated. – filpa Nov 18 '21 at 09:31
4

Just for completness, the "several variables" case is indeed possible, though not elegant at all. For example, for variables o, p, and q:

Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )

Please note the use of orElseGet() attending to the case that o, p, and q are not variables but expressions either expensive or with undesired side-effects.

In the most general case coalesce(e[1],e[2],e[3],...,e[N])

coalesce-expression(i) ==  e[i]  when i = N
coalesce-expression(i) ==  Optional.ofNullable( e[i] ).orElseGet(()-> coalesce-expression(i+1) )  when i < N

This can generate expressions excessively long. However, if we are trying to move to a world without null, then v[i] are most probably already of type Optional<String>, as opposed to simply String. In this case,

result= o.orElse(p.orElse(q.get())) ;

or in the case of expressions:

result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;

Furthermore, if you are also moving to a functional-declarative style, o, p, and q should be of type Supplier<String> like in:

Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;

And then the whole coalesce reduces simply to o.get().

For a more concrete example:

Supplier<Integer> hardcodedDefaultAge= ()-> 99 ;
Supplier<Integer> defaultAge= ()-> defaultAgeFromDatabase().orElseGet( hardcodedDefaultAge ) ;
Supplier<Integer> ageInStore= ()-> ageFromDatabase(memberId).orElseGet( defaultAge ) ;
Supplier<Integer> effectiveAge= ()-> ageFromInput().orElseGet( ageInStore ) ;

defaultAgeFromDatabase(), ageFromDatabase(), and ageFromInput() would already return Optional<Integer>, naturally.

And then the coalesce becomes effectiveAge.get() or simply effectiveAge if we are happy with a Supplier<Integer>.

IMHO, with Java 8 we will see more and more code structured like this, as it's extremely self-explainatory and efficient at the same time, especially in more complex cases.

I do miss a class Lazy<T> that invokes a Supplier<T> only one time, but lazily, as well as consistency in the definition of Optional<T> (i.e. Optional<T>-Optional<T> operators, or even Supplier<Optional<T>>).

Mario Rossi
  • 7,651
  • 27
  • 37
0

How about:

firstNonNull = FluentIterable.from(
    Lists.newArrayList( a, b, c, ... ) )
        .firstMatch( Predicates.notNull() )
            .or( someKnownNonNullDefault );

Java ArrayList conveniently allows null entries and this expression is consistent regardless of the number of objects to be considered. (In this form, all the objects considered need to be of the same type.)

Lonnie
  • 88
  • 1
  • 6
-2
Object coalesce(Object... objects)
{
    for(Object o : object)
        if(o != null)
            return o;
    return null;
}
Eric
  • 95,302
  • 53
  • 242
  • 374
  • 2
    God 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 – Bill K May 04 '10 at 18:51
  • Yeah, generics are the way to go. But I'm not all that familiar with the intricacies. – Eric May 04 '10 at 19:05
  • 11
    Time 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. – Avi May 04 '10 at 19:13
  • 1
    I 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. – Eric May 04 '10 at 20:18