    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.lang3;
    019
    020import java.util.stream.IntStream;
    021
    022/**
    023 * Specializes {@link NumberRange} for {@link Integer}s.
    024 *
    025 * <p>
    026 * This class is not designed to interoperate with other NumberRanges
    027 * </p>
    028 *
    029 * @since 3.13.0
    030 */
    031public final class IntegerRange extends NumberRange<Integer> {
    032
    033    private static final long serialVersionUID = 1L;
    034
    035    /**
    036     * Creates a closed range with the specified minimum and maximum values (both inclusive).
    037     *
    038     * <p>
    039     * The range uses the natural ordering of the elements to determine where values lie in the range.
    040     * </p>
    041     *
    042     * <p>
    043     * The arguments may be passed in the order (min,max) or (max,min). The getMinimum and getMaximum methods will return the correct values.
    044     * </p>
    045     *
    046     * @param fromInclusive the first value that defines the edge of the range, inclusive.
    047     * @param toInclusive the second value that defines the edge of the range, inclusive.
    048     * @return the range object, not null.
    049     */
    050    public static IntegerRange of(final int fromInclusive, final int toInclusive) {
    051        return of(Integer.valueOf(fromInclusive), Integer.valueOf(toInclusive));
    052    }
    053
    054    /**
    055     * Creates a closed range with the specified minimum and maximum values (both inclusive).
    056     *
    057     * <p>
    058     * The range uses the natural ordering of the elements to determine where values lie in the range.
    059     * </p>
    060     *
    061     * <p>
    062     * The arguments may be passed in the order (min,max) or (max,min). The getMinimum and getMaximum methods will return the correct values.
    063     * </p>
    064     *
    065     * @param fromInclusive the first value that defines the edge of the range, inclusive.
    066     * @param toInclusive the second value that defines the edge of the range, inclusive.
    067     * @return the range object, not null.
    068     * @throws IllegalArgumentException if either element is null.
    069     */
    070    public static IntegerRange of(final Integer fromInclusive, final Integer toInclusive) {
    071        return new IntegerRange(fromInclusive, toInclusive);
    072    }
    073
    074    /**
    075     * Creates a new instance.
    076     *
    077     * @param number1 the first element, not null
    078     * @param number2 the second element, not null
    079     * @throws NullPointerException when element1 is null.
    080     * @throws NullPointerException when element2 is null.
    081     */
    082    private IntegerRange(final Integer number1, final Integer number2) {
    083        super(number1, number2, null);
    084    }
    085
    086    /**
    087     * Fits the given value into this range by returning the given value or, if out of bounds, the range minimum if
    088     * below, or the range maximum if above.
    089     *
    090     * <pre>{@code
    091     * IntegerRange range = IntegerRange.of(16, 64);
    092     * range.fit(-9) -->  16
    093     * range.fit(0)  -->  16
    094     * range.fit(15) -->  16
    095     * range.fit(16) -->  16
    096     * range.fit(17) -->  17
    097     * ...
    098     * range.fit(63) -->  63
    099     * range.fit(64) -->  64
    100     * range.fit(99) -->  64
    101     * }</pre>
    102     *
    103     * @param element the element to test.
    104     * @return the minimum, the element, or the maximum depending on the element's location relative to the range.
    105     * @since 3.19.0
    106     */
    107    public int fit(final int element) {
    108        return super.fit(element).intValue();
    109    }
    110
    111    /**
    112     * Returns a sequential ordered {@code IntStream} from {@link #getMinimum()} (inclusive) to {@link #getMaximum()} (inclusive) by an incremental step of
    113     * {@code 1}.
    114     *
    115     * @return a sequential {@code IntStream} for the range of {@code int} elements
    116     * @since 3.18.0
    117     */
    118    public IntStream toIntStream() {
    119        return IntStream.rangeClosed(getMinimum(), getMaximum());
    120    }
    121}