View Javadoc

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 }