Skip to content

Instantly share code, notes, and snippets.

@ademar111190
Created January 3, 2019 14:07
Show Gist options
  • Save ademar111190/5654d21f66207b77812787d35f898fb7 to your computer and use it in GitHub Desktop.
Save ademar111190/5654d21f66207b77812787d35f898fb7 to your computer and use it in GitHub Desktop.
An optional implementation in java
package functional;
public interface Consumer0 {
void consume();
}
package functional;
public interface Consumer1<Arg1> {
void consume(@NonNull Arg1 arg1);
}
package functional;
public interface Consumer2<Arg1, Arg2> {
void consume(@NonNull Arg1 arg1, @NonNull Arg2 arg2);
}
package functional;
public interface Function0<Return> {
@NonNull
Return invoke();
}
package functional;
public interface Function1<Arg1, Return> {
@NonNull
Return invoke(@NonNull Arg1 arg1);
}
package functional;
public abstract class Optional<T> {
public abstract boolean isEmpty();
@NonNull
public abstract T getOrThrow() throws IllegalAccessException;
@Nullable
public abstract T getOrNull();
@NonNull
public abstract T getOrElse(@NonNull T def);
@NonNull
public abstract T getOrElse(@NonNull Function0<T> supply);
@NonNull
public abstract Optional<T> ifPresent(@NonNull Consumer1<T> consumer);
@NonNull
public abstract Optional<T> ifAbsent(@NonNull Consumer0 consumer);
@NonNull
public abstract Optional<T> filter(@NonNull Function1<T, Boolean> filter);
@NonNull
public abstract <R> Optional<R> map(@NonNull Function1<T, R> mapper);
@NonNull
public abstract <R> Optional<R> map(@NonNull UnsafeFunction1<T, R> mapper);
private Optional() {}
@NonNull
public static <T> Optional<T> of(@Nullable T t) {
return t == null ? new Empty<T>() : new Head<>(t);
}
@NonNull
public static <T> Optional<T> optional(@Nullable T t) {
return of(t);
}
@NonNull
public static <T> Optional<T> optional() {
return new Empty<>();
}
private static class Empty<T> extends Optional<T> {
private Empty() {
}
@Override
public boolean isEmpty() {
return true;
}
@NonNull
@Override
public T getOrThrow() throws IllegalAccessException {
throw new IllegalAccessException("You can not call get when Optional is empty");
}
@Nullable
@Override
public T getOrNull() {
return null;
}
@NonNull
@Override
public T getOrElse(@NonNull T def) {
return def;
}
@NonNull
@Override
public T getOrElse(@NonNull Function0<T> supply) {
return supply.invoke();
}
@NonNull
@Override
public Optional<T> ifPresent(@NonNull Consumer1<T> consumer) {
return this;
}
@NonNull
@Override
public Optional<T> ifAbsent(@NonNull Consumer0 consumer) {
consumer.consume();
return this;
}
@NonNull
@Override
public Optional<T> filter(@NonNull Function1<T, Boolean> filter) {
return this;
}
@NonNull
@Override
public <R> Optional<R> map(@NonNull Function1<T, R> mapper) {
return new Empty<>();
}
@NonNull
@Override
public <R> Optional<R> map(@NonNull UnsafeFunction1<T, R> mapper) {
return new Empty<>();
}
}
private static class Head<T> extends Optional<T> {
@NonNull private final T t;
private Head(@NonNull T t) {
this.t = t;
}
@Override
public boolean isEmpty() {
return false;
}
@NonNull
@Override
public T getOrThrow() {
return t;
}
@Nullable
@Override
public T getOrNull() {
return t;
}
@NonNull
@Override
public T getOrElse(@NonNull T def) {
return t;
}
@NonNull
@Override
public T getOrElse(@NonNull Function0<T> supply) {
return t;
}
@NonNull
@Override
public Optional<T> ifPresent(@NonNull Consumer1<T> consumer) {
consumer.consume(t);
return this;
}
@NonNull
@Override
public Optional<T> ifAbsent(@NonNull Consumer0 consumer) {
return this;
}
@NonNull
@Override
public Optional<T> filter(@NonNull Function1<T, Boolean> filter) {
return filter.invoke(t) ? this : new Empty<T>();
}
@NonNull
@Override
public <R> Optional<R> map(@NonNull Function1<T, R> mapper) {
return new Head<>(mapper.invoke(t));
}
@NonNull
@Override
public <R> Optional<R> map(@NonNull UnsafeFunction1<T, R> mapper) {
R r;
try {
r = mapper.invoke(t);
} catch (Exception e) {
return new Empty<>();
}
return new Head<>(r);
}
}
public static class IllegalAccessException extends Exception {
IllegalAccessException(@NonNull String message) {
super(message);
}
}
}
package functional;
public interface UnsafeFunction1<Arg1, Return> {
@NonNull
Return invoke(@NonNull Arg1 arg1) throws Exception;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment