59

Does Guava provide a method to get a default value if a passed object reference is null ? I'am looking for something like <T> T nullToDefault(T obj, T default), were the default is returned if obj is null.

Here on stackoverflow I found nothing about it. I am only looking for a pure Guava solution (if there is some)!

I found nothing in the Gauva 10 API, only com.google.common.base.Objects looks promising but lacks something similar.

Chriss
  • 5,157
  • 7
  • 41
  • 75

10 Answers10

74

In additon to Objects.firstNonNull, Guava 10.0 added the Optional class as a more general solution to this type of problem.

An Optional is something that may or may not contain a value. There are various ways of creating an Optional instance, but for your case the factory method Optional.fromNullable(T) is appropriate.

Once you have an Optional, you can use one of the or methods to get the value the Optional contains (if it contains a value) or some other value (if it does not).

Putting it all together, your simple example would look like:

T value = Optional.fromNullable(obj).or(defaultValue);

The extra flexibility of Optional comes in if you want to use a Supplier for the default value (so you don't do the calculation to get it unless necessary) or if you want to chain multiple optional values together to get the first value that is present, for example:

T value = someOptional.or(someOtherOptional).or(someDefault);
ColinD
  • 108,630
  • 30
  • 201
  • 202
  • Interesting ! Can it be used for null-safe operations with `Optional` instances of different type-parameters? I guess not, because it is all bound to the type of T? We have to wait for the [elvis-operator](https://docs.google.com/Doc?docid=ddb3zt39_78frdf87dc&hl=en&pli=1) in java 8+. – Chriss Nov 07 '11 at 21:46
  • Are you saying you want something like `Pet pet = Optional.fromNullable(cat).or(Optional.fromNullable(dog)).orNull()`, where `Cat` and `Dog` both extend `Pet`. It looks like you'd have to cast the first optional as a `Pet` first, then you'd be alright from there. – Ray Nov 08 '11 at 10:47
  • I consider that a performance anti-pattern, considering that it will create at least one object (and possibly two if the default value is e.g. an empty array) – David Burström Jun 22 '16 at 12:53
  • @DavidBurström: If you're on Android, that matters... otherwise, it most likely doesn't, or at least not nearly enough to worry about. – ColinD Jun 22 '16 at 16:40
  • Update: Benchmarking on JDK 1.8u91 shows equal performance once JIT kicks in. I'll get back with numbers for ART. – David Burström Jun 23 '16 at 06:20
  • 1
    Update: Running on Android 22 shows that in case the object is null, it takes 4 times as much time with Optional than doing simple conditionals. And in case the object is not null, it takes 14 times as much time. If you're also creating the default value unnecessarily, there's a further penalty depending on the type of course. – David Burström Jun 23 '16 at 08:53
61

How about

MoreObjects.firstNonNull(obj, default)

See the JavaDoc.

(Historical note: the MoreObjects class used to be called Objects, but it got renamed to avoid confusion with the java.util.Objects class introduced in Java 7. The Guava Objects class is now effectively deprecated.)

palacsint
  • 28,416
  • 10
  • 82
  • 109
Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127
  • 1
    The method name is a bit confusing in my use case. I guess i have to read it 2x to remember that i intendet to get the default value! But hey, it works ! – Chriss Nov 07 '11 at 16:50
  • This is deprecated now, the [guava doc](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Objects.html#firstNonNull(T,%20T)) advice to use `MoreObjects.firstNonNull(obj, default)` – antogerva Feb 01 '15 at 18:23
  • @antogerva Thanks - I've updated my answer to recommend MoreObjects instead. – Simon Nickerson Apr 10 '15 at 14:38
  • keep in mind that this method requires any of the arguments to be non null and it's not suitable for cases where default can be null – kairius Feb 11 '19 at 15:39
42

As said previously, the Guava solution is correct.

There is however a pure JDK solution with Java 8 :

Optional.ofNullable( var ).orElse( defaultValue );

See documentation of java.util.Optional

Nicolas Nobelis
  • 772
  • 6
  • 10
9

This should do the trick: Objects.firstNonNull(o, default)
See guava API doc

Jens Hoffmann
  • 6,699
  • 2
  • 25
  • 31
8

If you are only talking about Strings, there is also Apache Commons defaultString and defaultIfEmpty methods

defaultString will only give you the default on a true null whereas defaultIfEmpty will give you the default on a null or an empty string.

There is also defaultIfBlank which will give you the default even on a blank string.

e.g.

String description = "";
description = StringUtils.defaultIfBlank(description, "Theodore"); 

description will now equal "Theodore"

Edit: Apache Commons also has an ObjectUtils class that does null defaults for fully baked objects...

Daniel Schmidt
  • 401
  • 5
  • 5
7

If your object is not already an Optional, then the Optional/firstNotNull suggestions complicate what is a simple Java feature, the ternary operator:

T myVal = (val != null) ? val : defaultVal;

Including a dependency and multiple methods calls introduces as much reading complexity as the ternary operator. I would even argue that using Optional contrary to its 'my method may or may not be returning an object' semantics is a red flag that you are doing something wrong (just as in other cases where one abuses something contrary to that thing's semantic meaning).

See http://alvinalexander.com/java/edu/pj/pj010018 for more discussion about the ternary operator.

MonkeyWithDarts
  • 755
  • 1
  • 7
  • 17
  • 1
    I think you have a point. However, the optional solution is better if you want to test an expensive method return: `Optional.ofNullable( superExpensiveMethod() ).orElse( defaultValue );` With ternary, you would have to put it in a variable first. – Nicolas Nobelis Feb 26 '18 at 08:32
7

Just FYI, Java 9 has two methods that do exactly what you want:

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

And a lazy version:

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
3

java.util.Objects and Guava's optional do provide nice way for getting overriding null to default values... been using them a lot

But here is something for more imperative minded :

public static <T> T firstNotNuLL(T...args){
    for (T arg : args)
        if ( arg != null) return arg;
    throw new NullPointerException();  
}
1

You may use ObjectUtils.defaultIfNull() from org.apache.commons.lang3 library:

public static <T> T defaultIfNull(T object, T defaultValue)
Ilya Serbis
  • 21,149
  • 6
  • 87
  • 74
0

Consider using the Optional built into Guava 10. You could string together multiple optionals, like Optional.fromNullable(var).orNull() or Optional.fromNullable(var).or(Optional.of(var2)).orNull()

Ray
  • 4,829
  • 4
  • 28
  • 55