
com.github.sirikid.Maybe Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of maybe Show documentation
Show all versions of maybe Show documentation
Implementation Maybe monad in Java
The newest version!
/*
* Copyright (c) 2016, Ivan Sokolov. All rights reserved.
* This code is licensed under MIT license (see LICENSE for details)
*/
package com.github.sirikid;
import com.github.sirikid.iterators.EmptyIterator;
import com.github.sirikid.iterators.EmptySpliterator;
import com.github.sirikid.iterators.SingletonIterator;
import com.github.sirikid.iterators.SingletonSpliterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import static java.util.Objects.requireNonNull;
/**
* Implementation Maybe monad in Java.
*
* @author Ivan Sokolov
* @version 1.0.0
* @param type of value, if exists
* @since 1.0.0
*/
// TODO JavaDoc
public abstract class Maybe implements Supplier, Iterable {
private Maybe() { /* Get out, looser */ }
/**
* @return value, if present
* @throws NoSuchElementException otherwise
*/
@Nullable
@Override
public abstract T get();
/**
* Just synonym for {@link #get()}.
* @return value, if present
* @throws NoSuchElementException otherwise
*/
@Nullable
public final T unwrap() {
return get();
}
/**
* @param defaultValue default value
* @return value, if present, defaultValue otherwise
*/
@Nullable
public abstract T or(@Nullable T defaultValue);
/**
* Returns value or throws user defined exception.
*
* @param type of exception you want
* @param exceptionSupplier supplier, that supply exception you want
*
* @return value, if present
* @throws X instance of X otherwise
*/
@Nullable
public abstract T orThrow(Supplier exceptionSupplier) throws X;
/**
* @return true, if value present, false otherwise
*/
public abstract boolean exists();
/**
* If value exists consume value with given consumer.
*
* @param consumer just consumer
* @throws NullPointerException if consumer is null
*/
public abstract void ifExists(Consumer super T> consumer);
public abstract Maybe map(Function super T, ? extends U> mapper);
public abstract Maybe flatMap(Function super T, Maybe> mapper);
public abstract Maybe filter(Predicate super T> predicate);
public static Maybe nothing() {
return new Nothing<>();
}
public static Maybe just(@Nullable final T value) {
return new Just<>(value);
}
public static Maybe nonNull(@Nullable final T value) {
return (value == null) ? nothing() : just(value);
}
/**
* @since 1.1.0
* @throws NullPointerException if supplier is null
*/
public static Maybe exceptionally(Supplier supplier) {
return exceptionally(supplier, Throwable.class);
}
/**
* @since 1.1.0
* @throws NullPointerException if supplier or exceptionType is null
*/
public static Maybe exceptionally(Supplier supplier,
Class exceptionType) {
requireNonNull(supplier);
requireNonNull(exceptionType);
try {
return just(supplier.get());
} catch (Throwable t) {
if (exceptionType.isInstance(t)) return nothing();
throw t;
}
}
/**
* @since 1.1.0
* @throws NullPointerException if supplier or exceptionsTypes is null
*/
@SafeVarargs
public static Maybe exceptionally(Supplier supplier,
Class extends Throwable>... exceptionsTypes) {
requireNonNull(supplier);
requireNonNull(exceptionsTypes);
try {
return just(supplier.get());
} catch (Throwable t) {
for (final Class extends Throwable> type : exceptionsTypes)
if (type.isInstance(t)) return nothing();
throw t;
}
}
private final static class Nothing extends Maybe {
private Nothing() {}
@Nullable
@Override
public T get() {
throw new NoSuchElementException();
}
@Nullable
@Override
public T or(@Nullable final T defaultValue) {
return defaultValue;
}
@Nullable
@Override
public T orThrow(Supplier exceptionSupplier) throws X {
throw exceptionSupplier.get();
}
@Override
public boolean exists() {
return false;
}
@Override
public void ifExists(Consumer super T> consumer) {
requireNonNull(consumer);
}
@Override
public Maybe map(Function super T, ? extends U> mapper) {
requireNonNull(mapper);
return nothing();
}
@Override
public Maybe flatMap(Function super T, Maybe> mapper) {
requireNonNull(mapper);
return nothing();
}
@Override
public Maybe filter(Predicate super T> predicate) {
requireNonNull(predicate);
return nothing();
}
@Override
public Iterator iterator() {
return new EmptyIterator<>();
}
@Override
public Spliterator spliterator() {
return new EmptySpliterator<>();
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object obj) {
return obj == this || obj instanceof Nothing;
}
@Override
public String toString() {
return "Maybe.nothing";
}
}
private final static class Just extends Maybe {
@Nullable private final T value;
private Just(@Nullable final T value) {
this.value = value;
}
@Nullable
@Override
public T get() {
return value;
}
@Nullable
@Override
public T or(@Nullable T defaultValue) {
return value;
}
@Nullable
@Override
public T orThrow(Supplier exceptionSupplier) throws X {
return value;
}
@Override
public boolean exists() {
return true;
}
@Override
public void ifExists(Consumer super T> consumer) {
requireNonNull(consumer).accept(value);
}
@Override
public Maybe map(Function super T, ? extends U> mapper) {
return just(requireNonNull(mapper).apply(value));
}
@Override
public Maybe flatMap(Function super T, Maybe> mapper) {
return requireNonNull(mapper).apply(value);
}
@Override
public Maybe filter(Predicate super T> predicate) {
requireNonNull(predicate);
return predicate.test(value) ? just(value) : nothing();
}
@Override
public Iterator iterator() {
return new SingletonIterator<>(value);
}
@Override
public Spliterator spliterator() {
return new SingletonSpliterator<>(value);
}
@Override
public int hashCode() {
return Objects.hashCode(value);
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj instanceof Just) {
Just other = (Just) obj;
return Objects.equals(value, other.value);
}
return false;
}
@Override
public String toString() {
return "Maybe.just(" + String.valueOf(value) + ")";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy