In Java 8, I want to do something to an Optional
object if it is present, and do another thing if it is not present.
if (opt.isPresent()) { System.out.println("found"); } else { System.out.println("Not found"); }
This is not a 'functional style', though.
Optional
has an ifPresent()
method, but I am unable to chain an orElse()
method.
Thus, I cannot write:
opt.ifPresent( x -> System.out.println("found " + x)) .orElse( System.out.println("NOT FOUND"));
In reply to @assylias, I don't think Optional.map()
works for the following case:
opt.map( o -> { System.out.println("while opt is present..."); o.setProperty(xxx); dao.update(o); return null; }).orElseGet( () -> { System.out.println("create new obj"); dao.save(new obj); return null; });
In this case, when opt
is present, I update its property and save to the database. When it is not available, I create a new obj
and save to the database.
Note in the two lambdas I have to return null
.
But when opt
is present, both lambdas will be executed. obj
will be updated, and a new object will be saved to the database . This is because of the return null
in the first lambda. And orElseGet()
will continue to execute.
Advertisements. Optional is a container object used to contain not-null objects. Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as 'available' or 'not available' instead of checking null values.
In Java, the Optional object is a container object which may or may not contain a value. The Optional class is present in the java.
If you are using Java 9+, you can use ifPresentOrElse()
method:
opt.ifPresentOrElse( value -> System.out.println("Found: " + value), () -> System.out.println("Not found") );
For me the answer of @Dane White is OK, first I did not like using Runnable
but I could not find any alternatives.
Here another implementation I preferred more:
public class OptionalConsumer<T> { private Optional<T> optional; private OptionalConsumer(Optional<T> optional) { this.optional = optional; } public static <T> OptionalConsumer<T> of(Optional<T> optional) { return new OptionalConsumer<>(optional); } public OptionalConsumer<T> ifPresent(Consumer<T> c) { optional.ifPresent(c); return this; } public OptionalConsumer<T> ifNotPresent(Runnable r) { if (!optional.isPresent()) { r.run(); } return this; } }
Then:
Optional<Any> o = Optional.of(...); OptionalConsumer.of(o).ifPresent(s -> System.out.println("isPresent " + s)) .ifNotPresent(() -> System.out.println("! isPresent"));
Update 1:
the above solution for the traditional way of development when you have the value and want to process it but what if I want to define the functionality and the execution will be then, check below enhancement;
public class OptionalConsumer<T> implements Consumer<Optional<T>> { private final Consumer<T> c; private final Runnable r; public OptionalConsumer(Consumer<T> c, Runnable r) { super(); this.c = c; this.r = r; } public static <T> OptionalConsumer<T> of(Consumer<T> c, Runnable r) { return new OptionalConsumer(c, r); } @Override public void accept(Optional<T> t) { if (t.isPresent()) { c.accept(t.get()); } else { r.run(); } }
Then could be used as:
Consumer<Optional<Integer>> c = OptionalConsumer.of( System.out::println, () -> System.out.println("Not fit") ); IntStream.range(0, 100) .boxed() .map(i -> Optional.of(i) .filter(j -> j % 2 == 0)) .forEach(c);
In this new code you have 3 things:
By the way, now its name is more descriptive it is actually Consumer<Optional<?>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With