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

groovy.lang.IntRange Maven / Gradle / Ivy

There is a newer version: 3.9
Show newest version
/*
 * Copyright 2003-2013 the original author or authors.
 *
 * Licensed 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 groovy.lang;

import org.codehaus.groovy.runtime.IteratorClosureAdapter;

import java.math.BigInteger;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * Represents a list of Integer objects from a specified int up (or down) to and including
 * a given to.

*

* This class is a copy of {@link ObjectRange} optimized for int. If you make any * changes to this class, you might consider making parallel changes to {@link ObjectRange}. * * @author James Strachan * @version $Revision$ */ public class IntRange extends AbstractList implements Range { /** * Iterates through each number in an IntRange. */ private class IntRangeIterator implements Iterator { /** * Counts from 0 up to size - 1. */ private int index; /** * The number of values in the range. */ private int size = size(); /** * The next value to return. */ private int value = reverse ? to : from; /** * {@inheritDoc} */ public boolean hasNext() { return index < size; } /** * {@inheritDoc} */ public Integer next() { if (index++ > 0) { if (index > size) { return null; } else { if (reverse) { --value; } else { ++value; } } } return Integer.valueOf(value); } /** * Not supported. * * @throws java.lang.UnsupportedOperationException * always */ public void remove() { IntRange.this.remove(index); } } /** * The first number in the range. from is always less than or equal to to. */ private int from; /** * The last number in the range. to is always greater than or equal to from. */ private int to; /** * If false, counts up from from to to. Otherwise, counts down * from to to from. */ private boolean reverse; /** * Creates a new IntRange. If from is greater * than to, a reverse range is created with * from and to swapped. * * @param from the first number in the range. * @param to the last number in the range. * @throws IllegalArgumentException if the range would contain more than * {@link Integer#MAX_VALUE} values. */ public IntRange(int from, int to) { if (from > to) { this.from = to; this.to = from; this.reverse = true; } else { this.from = from; this.to = to; } // size() an integer so ranges can have no more than Integer.MAX_VALUE elements if (this.to - this.from >= Integer.MAX_VALUE) { throw new IllegalArgumentException("range must have no more than " + Integer.MAX_VALUE + " elements"); } } /** * Creates a new IntRange. * * @param from the first value in the range. * @param to the last value in the range. * @param reverse true if the range should count from * to to from. * @throws IllegalArgumentException if from is greater than to. */ protected IntRange(int from, int to, boolean reverse) { if (from > to) { throw new IllegalArgumentException("'from' must be less than or equal to 'to'"); } this.from = from; this.to = to; this.reverse = reverse; } /** * Determines if this object is equal to another object. Delegates to * {@link AbstractList#equals(Object)} if that is anything * other than an {@link IntRange}. *

* It is not necessary to override hashCode, as * {@link AbstractList#hashCode()} provides a suitable hash code.

*

* Note that equals is generally handled by {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#equals(List,List)} * instead of this method. * * @param that the object to compare * @return true if the objects are equal */ public boolean equals(Object that) { return that instanceof IntRange ? equals((IntRange) that) : super.equals(that); } /** * Compares an {@link IntRange} to another {@link IntRange}. * * @param that the object to compare for equality * @return true if the ranges are equal */ public boolean equals(IntRange that) { return that != null && this.reverse == that.reverse && this.from == that.from && this.to == that.to; } /** * {@inheritDoc} */ public Integer getFrom() { return Integer.valueOf(from); } /** * {@inheritDoc} */ public Integer getTo() { return Integer.valueOf(to); } /** * Gets the 'from' value as an integer. * * @return the 'from' value as an integer. */ public int getFromInt() { return from; } /** * Gets the 'to' value as an integer. * * @return the 'to' value as an integer. */ public int getToInt() { return to; } /** * {@inheritDoc} */ public boolean isReverse() { return reverse; } public boolean containsWithinBounds(Object o) { return contains(o); } /** * {@inheritDoc} */ public Integer get(int index) { if (index < 0) { throw new IndexOutOfBoundsException("Index: " + index + " should not be negative"); } if (index >= size()) { throw new IndexOutOfBoundsException("Index: " + index + " too big for range: " + this); } int value = reverse ? to - index : index + from; return Integer.valueOf(value); } /** * {@inheritDoc} */ public int size() { return to - from + 1; } /** * {@inheritDoc} */ public Iterator iterator() { return new IntRangeIterator(); } /** * {@inheritDoc} */ public List subList(int fromIndex, int toIndex) { if (fromIndex < 0) { throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); } if (toIndex > size()) { throw new IndexOutOfBoundsException("toIndex = " + toIndex); } if (fromIndex > toIndex) { throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } if (fromIndex == toIndex) { return new EmptyRange(Integer.valueOf(from)); } return new IntRange(fromIndex + this.from, toIndex + this.from - 1, reverse); } /** * {@inheritDoc} */ public String toString() { return reverse ? "" + to + ".." + from : "" + from + ".." + to; } /** * {@inheritDoc} */ public String inspect() { return toString(); } /** * {@inheritDoc} */ public boolean contains(Object value) { if (value instanceof Integer) { Integer integer = (Integer) value; int i = integer.intValue(); return i >= from && i <= to; } if (value instanceof BigInteger) { BigInteger bigint = (BigInteger) value; return bigint.compareTo(BigInteger.valueOf(from)) >= 0 && bigint.compareTo(BigInteger.valueOf(to)) <= 0; } return false; } /** * {@inheritDoc} */ public boolean containsAll(Collection other) { if (other instanceof IntRange) { final IntRange range = (IntRange) other; return this.from <= range.from && range.to <= this.to; } return super.containsAll(other); } /** * {@inheritDoc} */ public void step(int step, Closure closure) { if (step == 0) { if (from != to) { throw new GroovyRuntimeException("Infinite loop detected due to step size of 0"); } else { return; // from == to and step == 0, nothing to do, so return } } if (reverse) { step = -step; } if (step > 0) { int value = from; while (value <= to) { closure.call(Integer.valueOf(value)); value = value + step; } } else { int value = to; while (value >= from) { closure.call(Integer.valueOf(value)); value = value + step; } } } /** * {@inheritDoc} */ public List step(int step) { IteratorClosureAdapter adapter = new IteratorClosureAdapter(this); step(step, adapter); return adapter.asList(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy