001 /*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014
015 package org.apache.commons.functor.generator.util;
016
017 import org.apache.commons.functor.UnaryProcedure;
018 import org.apache.commons.functor.generator.BaseGenerator;
019
020
021 /**
022 * A generator for the range <i>from</i> (inclusive) to <i>to</i> (exclusive).
023 *
024 * @since 1.0
025 * @version $Revision: 1156804 $ $Date: 2011-08-11 22:14:47 +0200 (Thu, 11 Aug 2011) $
026 * @author Jason Horman (jason@jhorman.org)
027 * @author Rodney Waldhoff
028 */
029 public final class IntegerRange extends BaseGenerator<Integer> {
030 // attributes
031 //---------------------------------------------------------------
032
033 private final int from;
034 private final int to;
035 private final int step;
036
037 // constructors
038 //---------------------------------------------------------------
039 /**
040 * Create a new IntegerRange.
041 * @param from start
042 * @param to end
043 */
044 public IntegerRange(Number from, Number to) {
045 this(from.intValue(), to.intValue());
046 }
047
048 /**
049 * Create a new IntegerRange.
050 * @param from start
051 * @param to end
052 * @param step increment
053 */
054 public IntegerRange(Number from, Number to, Number step) {
055 this(from.intValue(), to.intValue(), step.intValue());
056 }
057
058 /**
059 * Create a new IntegerRange.
060 * @param from start
061 * @param to end
062 */
063 public IntegerRange(int from, int to) {
064 this(from, to, defaultStep(from, to));
065 }
066
067 /**
068 * Create a new IntegerRange.
069 * @param from start
070 * @param to end
071 * @param step increment
072 */
073 public IntegerRange(int from, int to, int step) {
074 if (from != to && signOf(step) != signOf(to - from)) {
075 throw new IllegalArgumentException("Will never reach " + to + " from " + from + " using step " + step);
076 }
077 this.from = from;
078 this.to = to;
079 this.step = step;
080 }
081
082 // methods
083 //---------------------------------------------------------------
084 /**
085 * {@inheritDoc}
086 */
087 public void run(UnaryProcedure<? super Integer> proc) {
088 if (signOf(step) == -1) {
089 for (int i = from; i > to; i += step) {
090 proc.run(i);
091 }
092 } else {
093 for (int i = from; i < to; i += step) {
094 proc.run(i);
095 }
096 }
097 }
098
099 /**
100 * {@inheritDoc}
101 */
102 public String toString() {
103 return "IntegerRange<" + from + "," + to + "," + step + ">";
104 }
105
106 /**
107 * {@inheritDoc}
108 */
109 public boolean equals(Object obj) {
110 if (obj == this) {
111 return true;
112 }
113 if (!(obj instanceof IntegerRange)) {
114 return false;
115 }
116 IntegerRange that = (IntegerRange) obj;
117 return this.from == that.from && this.to == that.to && this.step == that.step;
118 }
119
120 /**
121 * {@inheritDoc}
122 */
123 public int hashCode() {
124 int hash = "IntegerRange".hashCode();
125 hash <<= 2;
126 hash ^= from;
127 hash <<= 2;
128 hash ^= to;
129 hash <<= 2;
130 hash ^= step;
131 return hash;
132 }
133
134 // private methods
135 //---------------------------------------------------------------
136 /**
137 * Get <code>value/|value|</code> (0 when value == 0).
138 * @param value to test
139 * @return int
140 */
141 private static int signOf(int value) {
142 return value < 0 ? -1 : value > 0 ? 1 : 0;
143 }
144
145 /**
146 * Calculate default step to get from <code>from</code> to <code>to</code>.
147 * @param from start
148 * @param to end
149 * @return int
150 */
151 private static int defaultStep(int from, int to) {
152 return from > to ? -1 : 1;
153 }
154
155 }