org.apache.commons.functor.generator.range.DoubleRange.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.commons.functor.generator.range.DoubleRange.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.functor.generator.range;

import org.apache.commons.functor.BinaryFunction;
import org.apache.commons.functor.UnaryProcedure;
import org.apache.commons.lang3.Validate;

/**
 * A generator for a range of doubles.
 *
 * @since 1.0
 * @version $Revision: $ $Date: $
 */
public class DoubleRange extends NumericRange<Double> {

    // attributes
    // ---------------------------------------------------------------
    /**
     * Left limit.
     */
    private final Endpoint<Double> leftEndpoint;

    /**
     * Right limit.
     */
    private final Endpoint<Double> rightEndpoint;

    /**
     * Increment step.
     */
    private final double step;

    /**
     * Calculate default step.
     */
    public static final BinaryFunction<Double, Double, Double> DEFAULT_STEP = new BinaryFunction<Double, Double, Double>() {

        public Double evaluate(Double left, Double right) {
            return left > right ? -1.0d : 1.0d;
        }
    };

    // constructors
    // ---------------------------------------------------------------
    /**
     * Create a new DoubleRange.
     *
     * @param from start
     * @param to end
     */
    public DoubleRange(Number from, Number to) {
        this(from.doubleValue(), to.doubleValue());
    }

    /**
     * Create a new DoubleRange.
     *
     * @param from start
     * @param to end
     * @param step increment
     */
    public DoubleRange(Number from, Number to, Number step) {
        this(from.doubleValue(), to.doubleValue(), step.doubleValue());
    }

    /**
     * Create a new DoubleRange.
     *
     * @param from start
     * @param to end
     */
    public DoubleRange(double from, double to) {
        this(from, to, DEFAULT_STEP.evaluate(from, to).intValue());
    }

    /**
     * Create a new DoubleRange.
     *
     * @param from start
     * @param to end
     * @param step increment
     */
    public DoubleRange(double from, double to, double step) {
        this(from, DEFAULT_LEFT_BOUND_TYPE, to, DEFAULT_RIGHT_BOUND_TYPE, step);
    }

    /**
     * Create a new DoubleRange.
     *
     * @param from start
     * @param leftBoundType type of left bound
     * @param to end
     * @param rightBoundType type of right bound
     * @param step increment
     */
    public DoubleRange(double from, BoundType leftBoundType, double to, BoundType rightBoundType, double step) {
        this.leftEndpoint = Validate.notNull(new Endpoint<Double>(from, leftBoundType),
                "Left Endpoint argument must not be null");
        this.rightEndpoint = Validate.notNull(new Endpoint<Double>(to, rightBoundType),
                "Right Endpoint argument must not be null");
        this.step = step;
        if (from != to && Math.signum(step) != Math.signum(to - from)) {
            throw new IllegalArgumentException("Will never reach " + to + " from " + from + " using step " + step);
        }
    }

    /**
     * Create a new DoubleRange.
     *
     * @param from start
     * @param to end
     * @param step increment
     */
    public DoubleRange(Endpoint<Double> from, Endpoint<Double> to, double step) {
        this.leftEndpoint = Validate.notNull(from, "Left Endpoint argument must not be null");
        this.rightEndpoint = Validate.notNull(to, "Right Endpoint argument must not be null");
        this.step = step;
        if (from != to
                && Math.signum(step) != Math.signum(to.getValue().doubleValue() - from.getValue().doubleValue())) {
            throw new IllegalArgumentException("Will never reach " + to + " from " + from + " using step " + step);
        }
    }

    // methods
    // ---------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public Endpoint<Double> getLeftEndpoint() {
        return this.leftEndpoint;
    }

    /**
     * {@inheritDoc}
     */
    public Endpoint<Double> getRightEndpoint() {
        return this.rightEndpoint;
    }

    /**
     * {@inheritDoc}
     */
    public Double getStep() {
        return this.step;
    }

    /**
     * {@inheritDoc}
     */
    public void run(UnaryProcedure<? super Double> proc) {
        final double step = this.getStep();
        final boolean includeLeftValue = this.getLeftEndpoint().getBoundType() == BoundType.CLOSED;
        final boolean includeRightValue = this.getRightEndpoint().getBoundType() == BoundType.CLOSED;
        final double leftValue = this.getLeftEndpoint().getValue();
        final double rightValue = this.getRightEndpoint().getValue();
        if (step < 0) {
            final double from = includeLeftValue ? leftValue : leftValue + step;
            if (includeRightValue) {
                for (double i = from; i >= rightValue; i += step) {
                    proc.run(i);
                }
            } else {
                for (double i = from; i > rightValue; i += step) {
                    proc.run(i);
                }
            }
        } else {
            final double from = includeLeftValue ? leftValue : leftValue + step;
            if (includeRightValue) {
                for (double i = from; i <= rightValue; i += step) {
                    proc.run(i);
                }
            } else {
                for (double i = from; i < rightValue; i += step) {
                    proc.run(i);
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "DoubleRange<" + this.leftEndpoint.toLeftString() + ", " + this.rightEndpoint.toRightString() + ", "
                + this.step + ">";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof DoubleRange)) {
            return false;
        }
        DoubleRange that = (DoubleRange) obj;
        return this.leftEndpoint.equals(that.leftEndpoint) && this.rightEndpoint.equals(that.rightEndpoint)
                && this.step == that.step;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        int hash = "DoubleRange".hashCode();
        hash <<= 2;
        hash ^= this.leftEndpoint.getValue().hashCode();
        hash <<= 2;
        hash ^= this.rightEndpoint.getValue().hashCode();
        hash <<= 2;
        hash ^= Double.valueOf(this.step).hashCode();
        return hash;
    }

}