How to get the first non-null value in Java?

125,632

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);
}
Share:
125,632

Related videos on Youtube

froadie
Author by

froadie

Updated on December 17, 2021

Comments

  • froadie
    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, 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.

    • Vishy
      Vishy about 14 years
      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.
    • Adam Gent
      Adam Gent about 12 years
      Caveat: Not all RDBMS short circuit on COALESCE. Oracle only recently started doing it.
    • Dmitry Ginzburg
      Dmitry Ginzburg about 9 years
      @BrainSlugs83 Seriously? Java should?
  • Bill K
    Bill K about 14 years
    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
  • les2
    les2 about 14 years
    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.
  • froadie
    froadie about 14 years
    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...
  • Eric
    Eric about 14 years
    Yeah, generics are the way to go. But I'm not all that familiar with the intricacies.
  • les2
    les2 about 14 years
    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.)
  • Carl Manaster
    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
    Avi about 14 years
    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.
  • Eric
    Eric about 14 years
    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.
  • les2
    les2 about 14 years
    this way makes it much less painful and less error prone to write the overloaded variants!
  • Admin
    Admin over 12 years
    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.
  • Pang
    Pang over 11 years
    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.
  • Ivan G.
    Ivan G. about 11 years
    this requires every argument to be precalculated before the call to coalesce, pointless for performance reasons
  • les2
    les2 about 11 years
    you should not use this function with expressions as there is no lazy evaluation in java ..... yet?
  • Michal Čizmazia
    Michal Čizmazia almost 11 years
    Hey, it does: java.lang.NullPointerException: use Optional.orNull() instead of Optional.or(null)
  • Michal Čizmazia
    Michal Čizmazia almost 11 years
    This does the trick: Optional.fromNullable(a).or(Optional.fromNullable(b)).orNull‌​()
  • Anton Shchastnyi
    Anton Shchastnyi over 10 years
    Good comment, Jake. This NullPointerException often restricts Objects.firstNonNull usage. However, it's Guava's approach to avoid nulls at all.
  • quantum
    quantum over 9 years
    Nice article - it would be nice to have it English, though.
  • davidwebster48
    davidwebster48 over 9 years
    That method is now deprecated, and the recommended alternative is MoreObjects.firstNonNull
  • HairOfTheDog
    HairOfTheDog about 9 years
    There's something about that blog page that doesn't work with Google Translate. :-(
  • OrangeDog
    OrangeDog about 8 years
    If NPE is undesired, then see this answer
  • Luke
    Luke almost 8 years
    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.
  • Inego
    Inego almost 5 years
    Why wrap the first argument in a Supplier if it will be inspected anyway? For the sake of uniformity?
  • kodlan
    kodlan almost 4 years
    I was looking for the same but for strings, and found out that there are SpringUtils.firstNonBlank(T...) and SpringUtils.firstNonBlank(T...) methods.
  • Vadzim
    Vadzim over 3 years
    Note that both methods listed here introduce performance implications due to extra objects allocation, unlike simple ternary operator or Guava's MoreObjects.firstNonNull.
  • Stephan Richter
    Stephan Richter about 3 years
    Possible without the use of optional: Object default = "some value"; Object res = ((res = getSomeNullable()) != null) ? res : default;
  • pyropunk51
    pyropunk51 about 3 years
    Stream.of(null,"a") will not work since the of function is annotated with @NonNull
  • filpa
    filpa over 2 years
    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.
  • Mattwmaster58
    Mattwmaster58 over 2 years
    Requires Android 30