mv200580
mv200580

Reputation: 722

Java Optional if object is not null - returns the method result, if null - returns default value

Is it possible to transform this code to a Java 8 Optional one-line expression?

long lastPollTime;
if (object != null) {
    lastPollTime = object.getTime();
} else {
    lastPollTime = 0;
}

i.e. if some object is not null, I need to call an object method and return its result, or else return 0. Optional.ofNullable().orElse() is not suitable, as it returns the object of the same type, but i need the result of the method call or some default value.

Upvotes: 41

Views: 104928

Answers (6)

Jekin Kalariya
Jekin Kalariya

Reputation: 3507

You can do like below with java 8

long lastPollTime = 
    Optional.ofNullable(object).isPresent() ? object.getTime() : 0;

or without using java8 like this

 long lastPollTime = (object != null) ? object.getTime() : 0;

Upvotes: 3

Null
Null

Reputation: 511

long lastPollTime = (object != null) ? object.getTime() : 0;

Upvotes: 5

caduceus
caduceus

Reputation: 1828

Re ternary vs optional, if you ever needed to nest them the optional ends up being easier to read

long lastPollTime = Optional.ofNullable(object1)
  .map(o -> o.getTime())
  .orElse(Optional.ofNullable(object2)
    .map(o -> o.getTime())
    .orElse(0));

Upvotes: 1

slim
slim

Reputation: 41223

A few forms:

long lastPollTime = Optional.ofNullable(object).map(o -> o.getTime()).orElse(0L);

long lastPollTime = Optional.ofNullable(object).map(YouObjectClass::getTime).orElse(0L);

long lastPollTime = Optional.ofNullable(object).isPresent() ? object.getTime() : 0;

long lastPollTime = object != null ? object.getTime() : 0;

Of these, the last one, which doesn't use Optional (and therefore doesn't strictly answer your question!) is simpler to read and has fewer runtime overheads, and so should be preferred.

Arguably, it's even simpler if you reverse the options:

long lastPollTime = object == null ? 0 : object.getTime();

... although you might prefer to have the default last -- it's a matter of personal taste.


If you really can't use ternary operators, and you're doing this a lot, you could write your own utility method:

public <T,U> U mapWithFallback(T obj, Function<T,U> function, U fallback) {
    if(obj == null) {
        return fallback;
    } else {
        return function.apply(obj);
    }
}

... callable as:

long lastPollTime = mapWithFallback(object, o -> o.getTime(), 0);

... or make a complete mockery of your no-ternaries check using:

public <T,U> U ifElse( Supplier<Boolean> a, Supplier<U> ifTrue, Supplier<U> ifFalse) {
     if(a.get()) {
          return ifTrue.get();
     } else {
          return ifFalse.get();
     }
}

long lastPollTime = ifElse( () -> object == null, () -> object.getTime(), () -> 0);

It's in even better taste to avoid null references altogether, so that this kind of check isn't needed -- for example using the Null Object pattern.

... or by writing methods that return Optional rather than potential nulls. Optional is a great class; use it. Just don't convert something to Optional purely so you can immediately check whether it's empty.

Upvotes: 104

F. Lumnitz
F. Lumnitz

Reputation: 698

long lastPollTime = Optional.ofNullable(object).map(o -> o.getTime()).orElse(0L);

Instead of o -> o.getTime() you could use a methods reference like ClassOfObject::getTime

Upvotes: 8

Vlad Bochenin
Vlad Bochenin

Reputation: 3072

long lastPollTime = Optional.ofNullable(object).map(YouObjectClass::getTime).orElse(0L);

Upvotes: 14

Related Questions