Package net.emaze.dysfunctional.ranges

Source Code of net.emaze.dysfunctional.ranges.DenseRange

package net.emaze.dysfunctional.ranges;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import net.emaze.dysfunctional.contracts.dbc;
import net.emaze.dysfunctional.equality.EqualsBuilder;
import net.emaze.dysfunctional.hashing.HashCodeBuilder;
import net.emaze.dysfunctional.options.Maybe;
import net.emaze.dysfunctional.order.Order;
import net.emaze.dysfunctional.order.SequencingPolicy;

/**
*
* @param <T>
* @author rferranti
*/
public class DenseRange<T> implements Range<T> {

    private final SequencingPolicy<T> sequencer;
    private final Comparator<Maybe<T>> comparator;
    private final T begin;
    private final Maybe<T> end;

    public DenseRange(SequencingPolicy<T> sequencer, Comparator<Maybe<T>> comparator, Endpoint left, T lower, Maybe<T> upper, Endpoint right) {
        dbc.precondition(sequencer != null, "trying to create a DenseRange<T> with a null SequencingPolicy<T>");
        dbc.precondition(comparator != null, "trying to create a DenseRange<T> with a null Comparator<T>");
        dbc.precondition(lower != null, "trying to create a DenseRange<T> with null lower bound");
        dbc.precondition(upper != null, "trying to create a DenseRange<T> with null upper bound");
        dbc.precondition(Order.of(comparator, Maybe.just(lower), upper) != Order.GT, "trying to create a DenseRange<T> a lower bound greater than upper bound");
        dbc.precondition(upper.hasValue() || right != Endpoint.Include, "cannot create a right inclusive range with right bound set as Nothing");
        this.sequencer = sequencer;
        this.comparator = comparator;
        this.begin = left == Endpoint.Include ? lower : sequencer.next(lower).value();
        this.end = upper.hasValue() && right == Endpoint.Include ? sequencer.next(upper.value()) : upper;
    }

    @Override
    public boolean contains(T element) {
        return Order.of(comparator, Maybe.just(element), Maybe.just(begin)).isGte() && Order.of(comparator, Maybe.just(element), end).isLt();
    }

    @Override
    public T begin() {
        return begin;
    }

    @Override
    public Maybe<T> end() {
        return end;
    }

    @Override
    public int compareTo(Range<T> other) {
        dbc.precondition(other != null, "comparing (compareTo) a DenseRange<T> with null");
        return new RangeComparator<T>(comparator).compare(this, other);
    }

    @Override
    public Iterator<T> iterator() {
        return new RangeIterator<T>(sequencer, comparator, begin, end);
    }

    @Override
    public boolean equals(Object rhs) {
        if (rhs instanceof DenseRange == false) {
            return false;
        }
        final DenseRange<T> other = (DenseRange<T>) rhs;
        final EqualsBuilder builder = new EqualsBuilder().append(this.sequencer, other.sequencer).
                append(this.comparator, other.comparator);
        if (!this.iterator().hasNext() && !other.iterator().hasNext()) {
            return builder.isEquals();
        }
        return builder.
                append(this.begin, other.begin).
                append(this.end, other.end).
                isEquals();
    }

    @Override
    public int hashCode() {
        final HashCodeBuilder builder = new HashCodeBuilder().append(sequencer).
                append(comparator);
        if (!iterator().hasNext()) {
            return builder.toHashCode();
        }
        return builder.append(begin).
                append(end).
                toHashCode();
    }

    @Override
    public String toString() {
        return String.format("[%s-%s)", begin, end.hasValue() ? end.value() : "...");
    }

    /**
     * Apples to apples (dense to dense) : yields false if this.lower >
     * other.upper or other.lower > this.upper Apples to oranges: (dense to
     * nonDense) yields nonDense.overlaps(dense)
     *
     * @param other
     * @return
     */
    @Override
    public boolean overlaps(Range<T> other) {
        dbc.precondition(other != null, "checking for overlaps between a DenseRange<T> and null");
        if (other instanceof DenseRange == false) {
            return other.overlaps(this);
        }
        return !Order.of(comparator, Maybe.just(this.begin()), other.end()).isGte() && !Order.of(comparator, Maybe.just(other.begin()), this.end()).isGte();
    }

    @Override
    public List<DenseRange<T>> densified() {
        return Collections.singletonList(this);
    }
}
TOP

Related Classes of net.emaze.dysfunctional.ranges.DenseRange

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.