Functional style of Java 8's Optional.ifPresent and if-not-Present?

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:

  1. can define the functionality before the existing of an object easy.
  2. not creating object reference for each Optional, only one, you have so less memory than less GC.
  3. it is implementing consumer for better usage with other components.

By the way, now its name is more descriptive it is actually Consumer<Optional<?>>


Java 9 introduces

ifPresentOrElse if a value is present, performs the given action with the value, otherwise performs the given empty-based action.

See excellent Optional in Java 8 cheat sheet.

It provides all answers for most use cases.

Short summary below

ifPresent() - do something when Optional is set

opt.ifPresent(x -> print(x)); 
opt.ifPresent(this::print);

filter() - reject (filter out) certain Optional values.

opt.filter(x -> x.contains("ab")).ifPresent(this::print);

map() - transform value if present

opt.map(String::trim).filter(t -> t.length() > 1).ifPresent(this::print);

orElse()/orElseGet() - turning empty Optional to default T

int len = opt.map(String::length).orElse(-1);
int len = opt.
    map(String::length).
    orElseGet(() -> slowDefault());     //orElseGet(this::slowDefault)

orElseThrow() - lazily throw exceptions on empty Optional

opt.
filter(s -> !s.isEmpty()).
map(s -> s.charAt(0)).
orElseThrow(IllegalArgumentException::new);