All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.iodesystems.fn.data.Option Maven / Gradle / Ivy

Go to download

Fn is a lazy Java Library that helps utilize some rudimentary functional concepts with more nounular objects

There is a newer version: 3.0.4
Show newest version
package com.iodesystems.fn.data;

import com.iodesystems.fn.aspects.Iterables;
import com.iodesystems.fn.logic.Where;
import java.util.Iterator;
import java.util.NoSuchElementException;

@SuppressWarnings("SameReturnValue")
public abstract class Option implements Iterable {

  @SuppressWarnings("StaticInitializerReferencesSubClass")
  private static final Empty EMPTY = new Empty<>();

  private static final Where> IS_PRESENT = Option::isPresent;

  private static final Where> IS_EMPTY = Option::isEmpty;

  @SuppressWarnings("unchecked")
  public static  Where> wherePresent() {
    return (Where) IS_PRESENT;
  }

  @SuppressWarnings("unchecked")
  public static  Where> whereEmpty() {
    return (Where) IS_EMPTY;
  }

  public static  Iterable unwrap(Iterable> options) {
    final Iterator> iterator = options.iterator();
    return new Iterable() {
      @Override
      public Iterator iterator() {
        return new Iterator() {
          private Option nextT;

          public boolean hasNext() {
            while (iterator.hasNext()) {
              nextT = iterator.next();
              if (nextT.isPresent()) {
                return true;
              }
            }
            return false;
          }

          public T next() {
            return nextT.get();
          }

          @Override
          public void remove() {
            throw new IllegalStateException();
          }
        };
      }
    };
  }

  public static  Option of(T item) {
    if (item == null) {
      return empty();
    } else {
      return new Present<>(item);
    }
  }

  @SuppressWarnings("unchecked")
  public static  Empty empty() {
    return (Empty) EMPTY;
  }

  public Iterator iterator() {
    return new Iterator() {
      boolean hasNext = true;

      public boolean hasNext() {
        if (hasNext) {
          hasNext = false;
          return true;
        } else {
          return false;
        }
      }

      public T next() {
        return get();
      }

      @Override
      public void remove() {
        throw new IllegalStateException();
      }
    };
  }

  public abstract T get();

  public abstract T orElse(T ifEmpty);

  public abstract boolean isEmpty();

  public abstract boolean isPresent();

  public abstract T orResolve(Generator with);

  public static class Empty extends Option {

    private Empty() {}

    @Override
    @SuppressWarnings("unchecked")
    public Iterator iterator() {
      return (Iterator) Iterables.EMPTY_ITERATOR;
    }

    @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
    @Override
    public boolean equals(Object obj) {
      return obj == EMPTY;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    @SuppressWarnings("UnusedReturnValue")
    @Override
    public T get() {
      throw new NoSuchElementException();
    }

    @Override
    public T orElse(T ifEmpty) {
      return ifEmpty;
    }

    @Override
    public boolean isEmpty() {
      return true;
    }

    @Override
    public boolean isPresent() {
      return false;
    }

    @Override
    public T orResolve(Generator with) {
      return with.next();
    }
  }

  public static class Present extends Option {

    private final T thing;

    private Present(T thing) {
      this.thing = thing;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      Present present = (Present) o;
      if (thing == present.thing) {
        return true;
      }
      if (thing != null) {
        return thing.equals(present.thing);
      }
      return false;
    }

    @Override
    public int hashCode() {
      return thing != null ? thing.hashCode() : 0;
    }

    @Override
    public T get() {
      return thing;
    }

    @Override
    public T orElse(T ifEmpty) {
      return thing;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean isPresent() {
      return true;
    }

    @Override
    public T orResolve(Generator with) {
      return thing;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy