Skip to content

Instantly share code, notes, and snippets.

@mathieuancelin
Created February 3, 2012 13:56
Show Gist options
  • Save mathieuancelin/1730275 to your computer and use it in GitHub Desktop.
Save mathieuancelin/1730275 to your computer and use it in GitHub Desktop.
public static abstract class Option<T> implements Iterable<T>, Serializable {
public abstract boolean isDefined();
public abstract boolean isEmpty();
public abstract T get();
public Option<T> orElse(T value) {
return isEmpty() ? Option.maybe(value) : this;
}
public T getOrElse(T value) {
return isEmpty() ? value : get();
}
public T getOrElse(Function<Unit, T> function) {
return isEmpty() ? function.apply(Unit.unit()) : get();
}
public T getOrElse(Callable<T> function) {
return isEmpty() ? function.apply() : get();
}
public T getOrNull() {
return isEmpty() ? null : get();
}
@Override
public <R> Option<R> map(Function<T, R> function) {
if (isDefined()) {
return Option.maybe(function.apply(get()));
}
return Option.none();
}
public static <T> None<T> none() {
return (None<T>) (Object) none;
}
public static <T> Some<T> some(T value) {
return new Some<T>(value);
}
public static <T> Maybe<T> maybe(T value) {
return new Maybe<T>(value);
}
}
public static class None<T> extends Option<T> {
@Override
public boolean isDefined() {
return false;
}
@Override
public T get() {
throw new IllegalStateException("No value");
}
@Override
public Iterator<T> iterator() {
return Collections.<T>emptyList().iterator();
}
@Override
public String toString() {
return "None";
}
@Override
public boolean isEmpty() {
return true;
}
}
public static class Some<T> extends Option<T> {
final T value;
public Some(T value) {
this.value = value;
}
@Override
public boolean isDefined() {
return true;
}
@Override
public T get() {
return value;
}
@Override
public Iterator<T> iterator() {
return Collections.singletonList(value).iterator();
}
@Override
public String toString() {
return "Some ( " + value + " )";
}
@Override
public boolean isEmpty() {
return false;
}
}
public static class Maybe<T> extends Option<T> {
private final T input;
public Maybe(T input) {
this.input = input;
}
@Override
public boolean isDefined() {
return !(input == null);
}
@Override
public T get() {
return input;
}
@Override
public Iterator<T> iterator() {
if (input == null) {
return Collections.<T>emptyList().iterator();
} else {
return Collections.singletonList(input).iterator();
}
}
@Override
public String toString() {
return "Maybe ( " + input + " )";
}
@Override
public boolean isEmpty() {
return !isDefined();
}
}
Option<String> optStr = Option.some("Hello");
ou
Option<String> optStr = Option.none();
ou
Option<String> optStr = Option.maybe(null);
for (String str : optStr) {
System.out.println(str.toUpperCase());
}
if (optStr.isDefined()) {
System.out.println(str.toUpperCase());
}
String str = optStr.getOrElse("Nothing");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment