/pd4j/src/main/java/org/bitbucket/pd4j/util/Option.java
Java | 237 lines | 185 code | 52 blank | 0 comment | 16 complexity | 01e8e2bcf2ebc2bb5a1dc2f9b0ca3a48 MD5 | raw file
- package org.bitbucket.pd4j.util;
- import java.io.Serializable;
- import java.util.Iterator;
- import java.util.Optional;
- import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.function.Predicate;
- import java.util.function.Supplier;
- import java.util.stream.Stream;
- public abstract class Option<T> implements Iterable<T>, Serializable {
- private final static long serialVersionUID = -1L;
- private final static Nothing<?> NOTHING = new Nothing<>();
- private Option() {
- }
- @SuppressWarnings("unchecked")
- public static <T> Option<T> nothing() {
- return (Option<T>) NOTHING;
- }
- public static <T> Option<T> some(T t) {
- return new Some<>(t);
- }
- public static <T> Option<T> from(Optional<T> optional) {
- if (optional.isPresent()) {
- return some(optional.get());
- } else {
- return nothing();
- }
- }
- public abstract Optional<T> toOptional();
- public abstract T getOrElse(Supplier<T> fallBack);
- public abstract boolean isNothing();
- public abstract <R> R fold(Supplier<R> ifNothing, Function<T, R> ifSome);
- public abstract void fold(Runnable ifNothing, Consumer<T> ifSome);
- public abstract Option<T> filter(Predicate<T> p);
- public abstract <R> Option<R> map(Function<T, R> fn);
- public abstract <R> Option<R> flatMap(Function<T, Option<R>> fn);
- public abstract Option<T> orElse(Option<T> fallBack);
- public abstract Stream<T> stream();
- @SafeVarargs
- public final Option<T> orElse(Supplier<Option<T>>... fallBacks) {
- Option<T> underEvaluation = this;
- for (Supplier<Option<T>> s : fallBacks) {
- if (underEvaluation.isNothing()) {
- underEvaluation = s.get();
- } else {
- break;
- }
- }
- return underEvaluation;
- }
- public static class Some<T> extends Option<T> {
- private final static long serialVersionUID = -1L;
- public final T value;
- private Some(T value) {
- this.value = value;
- }
- @Override
- public Optional<T> toOptional() {
- return Optional.ofNullable(value);
- }
- @Override
- public T getOrElse(Supplier<T> fallBack) {
- return value;
- }
- @Override
- public <R> R fold(Supplier<R> ifNothing, Function<T, R> ifSome) {
- return ifSome.apply(value);
- }
- @Override
- public void fold(Runnable ifNothing, Consumer<T> ifSome) {
- ifSome.accept(value);
- }
- @Override
- public Option<T> filter(Predicate<T> p) {
- if (p.test(value)) {
- return this;
- } else {
- return nothing();
- }
- }
- @Override
- public <R> Option<R> map(Function<T, R> fn) {
- return some(fn.apply(value));
- }
- @Override
- public <R> Option<R> flatMap(Function<T, Option<R>> fn) {
- return fn.apply(value);
- }
- @Override
- public Option<T> orElse(Option<T> fallBack) {
- return this;
- }
- @Override
- public boolean isNothing() {
- return false;
- }
- @Override
- public Stream<T> stream() {
- return Stream.of(value);
- }
- @Override
- public Iterator<T> iterator() {
- return new Iterator<T>() {
- boolean consumed;
- @Override
- public boolean hasNext() {
- return !consumed;
- }
- @Override
- public T next() {
- consumed = true;
- return value;
- }
- };
- }
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof Some)) {
- return false;
- }
- final Some<?> other = (Some<?>) obj;
- if (this.value != other.value && (this.value == null || !this.value.equals(other.value))) {
- return false;
- }
- return true;
- }
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
- return hash;
- }
- }
- public static class Nothing<T> extends Option<T> {
- private final static long serialVersionUID = -1L;
- private Nothing() { }
- @Override
- public Optional<T> toOptional() {
- return Optional.empty();
- }
- @Override
- public T getOrElse(Supplier<T> fallBack) {
- return fallBack.get();
- }
- @Override
- public <R> R fold(Supplier<R> ifNothing, Function<T, R> ifSome) {
- return ifNothing.get();
- }
- @Override
- public void fold(Runnable ifNothing, Consumer<T> ifSome) {
- ifNothing.run();
- }
- @Override
- public Option<T> filter(Predicate<T> p) {
- return nothing();
- }
- @Override
- public <R> Option<R> map(Function<T, R> fn) {
- return nothing();
- }
- @Override
- public <R> Option<R> flatMap(Function<T, Option<R>> fn) {
- return nothing();
- }
- @Override
- public Option<T> orElse(Option<T> fallBack) {
- return fallBack;
- }
- @Override
- public boolean isNothing() {
- return true;
- }
- @Override
- public Stream<T> stream() {
- return Stream.empty();
- }
- @Override
- public Iterator<T> iterator() {
- return EmptyIterator.instance();
- }
- }
- }