Reputation: 6116
I want to check if a particular object size is greater than 0. If it is greater than 0 then I want to create an optional object, if not then I want to return an empty optional. This is the long version of the Java code:
if(fooA.size>0) {
return Optional.of(new Foo());
} else {
return Optional.empty();
}
Is there any way to compact this into one line using the Optional
API introduced in Java 8?
Upvotes: 3
Views: 3265
Reputation: 23840
Is there any way to compact this into one line using java 8's optional library?
If you insist on using the Optional class, you could use Optional.ofNullable()
and just pass it null
if the condition isn't met:
return Optional.ofNullable(fooA.size > 0 ? new Foo() : null);
Note, however (as Holger correctly states) that using the Optional class doesn't give you any significant1 advantage over just replacing your if/else statement with a ternary one (as tobias_k and Holger have both done in their comments):
return fooA.size > 0 ? Optional.of(new Foo()) : Optional.empty();
1 The first line is a little shorter, which I usually consider an advantage, but an absolutely insignificant one in this case, as the length difference is negligible.
Upvotes: 8
Reputation: 11132
If you decide to stick to imperative programming, an if-else construct as yours is good as it is. Its readable, understandable and you gain nothing by simply reducing lines of code (unless you get paid for that and want to game the system).
The (condition)?(true-branch):(false-branch)
construct is nice but may become poorly readable if it gets too complex. Some auto-format rules put each part of it into separate lines anyway. So think before using it.
The simplest way for putting the creation into a single line is to refactor the instantiation into a separate method and invoke it:
return newOptionalFoo(fooA.size > 0);
...
private Optional<Foo> newOptionalFoo(boolean condition) {
if(condition) {
return Optional.of(new Foo());
} else {
return Optional.empty();
}
}
If you want to condense this to single line - imperative style - do this:
return condition ? Optional.of(new Foo()) : Optional.empty();
In case you want to use functional programming, you should not mix functional and imperative programming when it is avoidable.
A proper functional way would be to wrap fooA
into an Optional, filter on the condition and map to Foo
. So if condition is not fulfilled, it is mapped to the empty Optional
. I'd prefer this way.
return Optional.of(fooA).filter(f -> f.size > 0).map(f -> new Foo());
Alternatively you could create the Optional
of Foo
and use the filter so that the optional becomes empty if the filter condition does not match:
return Optional.of(new Foo()).filter(f -> fooA.size > 0);
But this would create an instance of Foo
regardless of the condition beeing true or false. If you want to have lazy instantiation because creating a Foo
is expensive, you could use a Supplier
and map to Foo
after filtering
return Optional.of((Supplier<Foo>) Foo::new)
.filter(s -> fooA.size > 0)
.map(Supplier::get)
Upvotes: 7