Created
January 3, 2019 14:07
-
-
Save ademar111190/5654d21f66207b77812787d35f898fb7 to your computer and use it in GitHub Desktop.
An optional implementation in java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package functional; | |
public interface Consumer0 { | |
void consume(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package functional; | |
public interface Consumer1<Arg1> { | |
void consume(@NonNull Arg1 arg1); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package functional; | |
public interface Consumer2<Arg1, Arg2> { | |
void consume(@NonNull Arg1 arg1, @NonNull Arg2 arg2); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package functional; | |
public interface Function0<Return> { | |
@NonNull | |
Return invoke(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package functional; | |
public interface Function1<Arg1, Return> { | |
@NonNull | |
Return invoke(@NonNull Arg1 arg1); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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