Skip to content

Instantly share code, notes, and snippets.

@npathai
Created August 9, 2014 13:22
Show Gist options
  • Save npathai/2a183fe1310df1670486 to your computer and use it in GitHub Desktop.
Save npathai/2a183fe1310df1670486 to your computer and use it in GitHub Desktop.
Using Optional in Java8 in a functional way using the flatMap operation to give it a monadic touch!
public abstract class Optional<T> {
public static <T> Optional<T> of(T value) {
return value != null ? new Present<T>(value) : Absent.<T>instance();
}
public <V> Optional<V> flatMap(Function<T, Optional<V>> function) {
return isPresent() ? function.apply(get()) : Absent.<V>instance();
}
public abstract T get();
public abstract boolean isPresent();
public abstract Optional<T> or(Optional<T> other);
public abstract T or(T defaultValue);
}
class Present<T> extends Optional<T> {
private final T value;
Present(T value) {
this.value = Objects.requireNonNull(value);
}
@Override
public T get() {
return value;
}
@Override
public boolean isPresent() {
return true;
}
@Override
public Optional<T> or(Optional<T> other) {
return this;
}
@Override
public T or(T defaultValue) {
return get();
}
}
class Absent<T> extends Optional<T> {
private static final Absent<Object> INSTANCE = new Absent<>();
private Absent() {}
@SuppressWarnings("unchecked")
public static <T> Optional<T> instance() {
return (Optional<T>) INSTANCE;
}
@Override
public T get() {
throw new UnsupportedOperationException("Cannot get on an absent instance");
}
@Override
public boolean isPresent() {
return false;
}
@Override
public Optional<T> or(Optional<T> other) {
return other;
}
@Override
public T or(T defaultValue) {
return defaultValue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment