tags:

views:

296

answers:

3

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.

+9  A: 

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 ...
}
LES2
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
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
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
p.s. you can still accept the answer if you think it's the right / best answer to the question (even if you will do something else)
LES2
+1  A: 
Object COALESCE(Object... objects)
{
    for(Object o : object)
        if(o != null)
            return o;
    return null;
}
Eric
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
Yeah, generics are the way to go. But I'm not all that familiar with the intricacies.
Eric
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
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
+2  A: 

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
+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
this way makes it much less painful and less error prone to write the overloaded variants!
LES2