1 /*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15 package org.apache.commons.functor.generator.util;
16
17 import org.apache.commons.functor.UnaryProcedure;
18 import org.apache.commons.functor.generator.BaseGenerator;
19
20
21 /**
22 * A generator for the range <i>from</i> (inclusive) to <i>to</i> (exclusive).
23 *
24 * @since 1.0
25 * @version $Revision: 1345136 $ $Date: 2012-06-01 08:47:06 -0400 (Fri, 01 Jun 2012) $
26 */
27 public final class IntegerRange extends BaseGenerator<Integer> {
28 // attributes
29 //---------------------------------------------------------------
30
31 /**
32 * The start index.
33 */
34 private final int from;
35
36 /**
37 * The end index.
38 */
39 private final int to;
40
41 /**
42 * The increment counter.
43 */
44 private final int step;
45
46 // constructors
47 //---------------------------------------------------------------
48 /**
49 * Create a new IntegerRange.
50 * @param from start
51 * @param to end
52 */
53 public IntegerRange(Number from, Number to) {
54 this(from.intValue(), to.intValue());
55 }
56
57 /**
58 * Create a new IntegerRange.
59 * @param from start
60 * @param to end
61 * @param step increment
62 */
63 public IntegerRange(Number from, Number to, Number step) {
64 this(from.intValue(), to.intValue(), step.intValue());
65 }
66
67 /**
68 * Create a new IntegerRange.
69 * @param from start
70 * @param to end
71 */
72 public IntegerRange(int from, int to) {
73 this(from, to, defaultStep(from, to));
74 }
75
76 /**
77 * Create a new IntegerRange.
78 * @param from start
79 * @param to end
80 * @param step increment
81 */
82 public IntegerRange(int from, int to, int step) {
83 if (from != to && signOf(step) != signOf(to - from)) {
84 throw new IllegalArgumentException("Will never reach " + to + " from " + from + " using step " + step);
85 }
86 this.from = from;
87 this.to = to;
88 this.step = step;
89 }
90
91 // methods
92 //---------------------------------------------------------------
93 /**
94 * {@inheritDoc}
95 */
96 public void run(UnaryProcedure<? super Integer> proc) {
97 if (signOf(step) == -1) {
98 for (int i = from; i > to; i += step) {
99 proc.run(Integer.valueOf(i));
100 }
101 } else {
102 for (int i = from; i < to; i += step) {
103 proc.run(Integer.valueOf(i));
104 }
105 }
106 }
107
108 /**
109 * {@inheritDoc}
110 */
111 @Override
112 public String toString() {
113 return "IntegerRange<" + from + "," + to + "," + step + ">";
114 }
115
116 /**
117 * {@inheritDoc}
118 */
119 @Override
120 public boolean equals(Object obj) {
121 if (obj == this) {
122 return true;
123 }
124 if (!(obj instanceof IntegerRange)) {
125 return false;
126 }
127 IntegerRange that = (IntegerRange) obj;
128 return this.from == that.from && this.to == that.to && this.step == that.step;
129 }
130
131 /**
132 * {@inheritDoc}
133 */
134 @Override
135 public int hashCode() {
136 int hash = "IntegerRange".hashCode();
137 hash <<= 2;
138 hash ^= from;
139 hash <<= 2;
140 hash ^= to;
141 hash <<= 2;
142 hash ^= step;
143 return hash;
144 }
145
146 // private methods
147 //---------------------------------------------------------------
148 /**
149 * Get <code>value/|value|</code> (0 when value == 0).
150 * @param value to test
151 * @return int
152 */
153 private static int signOf(int value) {
154 return value < 0 ? -1 : value > 0 ? 1 : 0;
155 }
156
157 /**
158 * Calculate default step to get from <code>from</code> to <code>to</code>.
159 * @param from start
160 * @param to end
161 * @return int
162 */
163 private static int defaultStep(int from, int to) {
164 return from > to ? -1 : 1;
165 }
166
167 }