froadie
froadie

Reputation: 83043

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

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.

Upvotes: 216

Views: 173665

Answers (14)

Per Lundberg
Per Lundberg

Reputation: 4221

(Similar to other answers, but I wanted to more exhaustively describe the differences between Guava's MoreObjects.firstNonNull(), Apache Commons Lang 3 ObjectUtils.firstNonNull() and the java.util.Objects.requireNonNullElse() and requireNonNullElseGet() methods introduced in Java 9.)

This answer is long - see the TL;DR at the end if you are want to just skip to the summary.

Guava MoreObjects.firstNonNull(T, T)

Guava's MoreObjects.firstNonNull(T, T) is described like this. The important part is the @throws NullPointerException if both {@code first} and {@code second} are null. This method requires that either one of the objects are non-null

public static <T> T firstNonNull​(@CheckForNull T first, @CheckForNull T second)

Returns the first of two given parameters that is not null, if either is, or otherwise throws a NullPointerException.

To find the first non-null element in an iterable, use Iterables.find(iterable, Predicates.notNull()). For varargs, use Iterables.find(Arrays.asList(a, b, c, ...), Predicates.notNull()), static importing as necessary.

Note: if first is represented as an Optional, this can be accomplished with first.or(second). That approach also allows for lazy evaluation of the fallback instance, using first.or(supplier).

Java 9 users: use java.util.Objects.requireNonNullElse(first, second)` instead.

Returns:
first if it is non-null; otherwise second if it is non-null

Throws:
java.lang.NullPointerException - if both first and second are null

Since:
18.0 (since 3.0 as Objects.firstNonNull()).

Apache Commons Lang 3 ObjectUtils.firstNonNull() and defaultIfNull(T, T)

ObjectUtils.firstNonNull(T...) on the other hand, has a much more "relaxed" handling of null values. If all values are null, well, then the method simply returns null. For some cases, this might be preferable (as long as the calling code handles null return values properly).

Also note that this takes a T... variable argument parameter, so it can be used with more than two parameters, unlike the other options.

public static <T> T firstNonNull(T... values)

Returns the first value in the array which is not null. If all the values are null or the array is null or empty then null is returned.

ObjectUtils.firstNonNull(null, null) = null ObjectUtils.firstNonNull(null, "") = "" ObjectUtils.firstNonNull(null, null, "") = "" ObjectUtils.firstNonNull(null, "zz") = "zz" ObjectUtils.firstNonNull("abc", *) = "abc" ObjectUtils.firstNonNull(null, "xyz", *) = "xyz" ObjectUtils.firstNonNull(Boolean.TRUE, *) = Boolean.TRUE ObjectUtils.firstNonNull() = null

Type Parameters:
T - the component type of the array

Parameters:
values - the values to test, may be null or empty

Returns:
the first value from values which is not null, or null if there are no non-null values

Since:
3.0

The ObjectUtils.defaultIfNull(T, T) method also exists, and has similar null semantics, but is slightly more optimized for the two-parameter scenario.

JDK java.util.Objects.requireNonNullElse and requireNonNullElseGet methods

Objects.requireNonNullElse(T, T) has the following semantics. It matches the Guava MoreObjects.firstNonNull() method quite closely, it should be pretty much a drop-in replacement for that method.

public static <T> T requireNonNullElse​(T obj, T defaultObj)

Returns the first argument if it is non-null and otherwise returns the non-null second argument.

Type Parameters:
T - the type of the reference

Parameters:
obj - an object
defaultObj - a non-null object to return if the first argument is null

Returns:
the first argument if it is non-null and otherwise the second argument if it is non-null

Throws:
NullPointerException - if both obj is null and defaultObj is null

Since:
9

Finally, the Objects.requireNonNullElseGet(T obj, Supplier<? extends T> supplier) method. It can be useful if creating the fallback value is a more heavy operation that you want to avoid if obj is non-null.

public static <T> T requireNonNullElseGet​(T obj, Supplier<? extends T> supplier)

Returns the first argument if it is non-null and otherwise returns the non-null value of supplier.get().

Type Parameters:
T - the type of the first argument and return type

Parameters:
obj - an object
supplier - of a non-null object to return if the first argument is null

Returns:
the first argument if it is non-null and otherwise the value from supplier.get() if it is non-null

Throws:
NullPointerException - if both obj is null and either the supplier is null or the supplier.get() value is null

Since: 9

TL;DR

Upvotes: 3

Andrzej Polis
Andrzej Polis

Reputation: 3387

Apache Commons Lang 3

ObjectUtils.defaultIfNull(T, T)

or less efficient but for more potential values:

ObjectUtils.firstNonNull(T...)

Java 8 Stream

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

Upvotes: 303

les2
les2

Reputation: 14469

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.

Upvotes: 137

Mert &#220;lkg&#252;n
Mert &#220;lkg&#252;n

Reputation: 154

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

Upvotes: 9

Triqui
Triqui

Reputation: 51

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);
}

Upvotes: 5

Lucas Le&#243;n
Lucas Le&#243;n

Reputation: 632

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

Upvotes: 8

Dave
Dave

Reputation: 5173

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

Upvotes: 67

Lonnie
Lonnie

Reputation: 86

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

Upvotes: 0

Christian Ullenboom
Christian Ullenboom

Reputation: 1458

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

Upvotes: 73

Mario Rossi
Mario Rossi

Reputation: 7799

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

Upvotes: 4

Franta
Franta

Reputation: 8117

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

Upvotes: 13

Jamol
Jamol

Reputation: 2291

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();

Upvotes: 5

Eric
Eric

Reputation: 97571

Object coalesce(Object... objects)
{
    for(Object o : object)
        if(o != null)
            return o;
    return null;
}

Upvotes: -2

Eric
Eric

Reputation: 97571

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);
}

Upvotes: 26

Related Questions