KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > lang > math > NumberRange


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.lang.math;
17
18 import java.io.Serializable JavaDoc;
19
20 /**
21  * <p><code>NumberRange</code> represents an inclusive range of
22  * {@link java.lang.Number} objects of the same type.</p>
23  *
24  * @author <a HREF="mailto:chrise@esha.com">Christopher Elkins</a>
25  * @author Stephen Colebourne
26  * @since 2.0 (previously in org.apache.commons.lang)
27  * @version $Id: NumberRange.java 161243 2005-04-14 04:30:28Z ggregory $
28  */

29 public final class NumberRange extends Range implements Serializable JavaDoc {
30     
31     private static final long serialVersionUID = 71849363892710L;
32
33     /**
34      * The minimum number in this range.
35      */

36     private final Number JavaDoc min;
37     /**
38      * The maximum number in this range.
39      */

40     private final Number JavaDoc max;
41     
42     /**
43      * Cached output hashCode (class is immutable).
44      */

45     private transient int hashCode = 0;
46     /**
47      * Cached output toString (class is immutable).
48      */

49     private transient String JavaDoc toString = null;
50
51     /**
52      * <p>Constructs a new <code>NumberRange</code> using the specified
53      * number as both the minimum and maximum in this range.</p>
54      *
55      * @param num the number to use for this range
56      * @throws IllegalArgumentException if the number is <code>null</code>
57      * @throws IllegalArgumentException if the number doesn't implement <code>Comparable</code>
58      * @throws IllegalArgumentException if the number is <code>Double.NaN</code> or <code>Float.NaN</code>
59      */

60     public NumberRange(Number JavaDoc num) {
61         if (num == null) {
62             throw new IllegalArgumentException JavaDoc("The number must not be null");
63         }
64         if (num instanceof Comparable JavaDoc == false) {
65             throw new IllegalArgumentException JavaDoc("The number must implement Comparable");
66         }
67         if (num instanceof Double JavaDoc && ((Double JavaDoc) num).isNaN()) {
68             throw new IllegalArgumentException JavaDoc("The number must not be NaN");
69         }
70         if (num instanceof Float JavaDoc && ((Float JavaDoc) num).isNaN()) {
71             throw new IllegalArgumentException JavaDoc("The number must not be NaN");
72         }
73
74         this.min = num;
75         this.max = num;
76     }
77
78     /**
79      * <p>Constructs a new <code>NumberRange</code> with the specified
80      * minimum and maximum numbers (both inclusive).</p>
81      *
82      * <p>The arguments may be passed in the order (min,max) or (max,min). The
83      * {@link #getMinimumNumber()} and {@link #getMaximumNumber()} methods will return the
84      * correct value.</p>
85      *
86      * <p>This constructor is designed to be used with two <code>Number</code>
87      * objects of the same type. If two objects of different types are passed in,
88      * an exception is thrown.</p>
89      *
90      * @param num1 first number that defines the edge of the range, inclusive
91      * @param num2 second number that defines the edge of the range, inclusive
92      * @throws IllegalArgumentException if either number is <code>null</code>
93      * @throws IllegalArgumentException if the numbers are of different types
94      * @throws IllegalArgumentException if the numbers don't implement <code>Comparable</code>
95      */

96     public NumberRange(Number JavaDoc num1, Number JavaDoc num2) {
97         if (num1 == null || num2 == null) {
98             throw new IllegalArgumentException JavaDoc("The numbers must not be null");
99         }
100         if (num1.getClass() != num2.getClass()) {
101             throw new IllegalArgumentException JavaDoc("The numbers must be of the same type");
102         }
103         if (num1 instanceof Comparable JavaDoc == false) {
104             throw new IllegalArgumentException JavaDoc("The numbers must implement Comparable");
105         }
106         if (num1 instanceof Double JavaDoc) {
107             if (((Double JavaDoc) num1).isNaN() || ((Double JavaDoc) num2).isNaN()) {
108                 throw new IllegalArgumentException JavaDoc("The number must not be NaN");
109             }
110         } else if (num1 instanceof Float JavaDoc) {
111             if (((Float JavaDoc) num1).isNaN() || ((Float JavaDoc) num2).isNaN()) {
112                 throw new IllegalArgumentException JavaDoc("The number must not be NaN");
113             }
114         }
115         
116         int compare = ((Comparable JavaDoc) num1).compareTo(num2);
117         if (compare == 0) {
118             this.min = num1;
119             this.max = num1;
120         } else if (compare > 0) {
121             this.min = num2;
122             this.max = num1;
123         } else {
124             this.min = num1;
125             this.max = num2;
126         }
127     }
128     
129     // Accessors
130
//--------------------------------------------------------------------
131

132     /**
133      * <p>Returns the minimum number in this range.</p>
134      *
135      * @return the minimum number in this range
136      */

137     public Number JavaDoc getMinimumNumber() {
138         return min;
139     }
140
141     /**
142      * <p>Returns the maximum number in this range.</p>
143      *
144      * @return the maximum number in this range
145      */

146     public Number JavaDoc getMaximumNumber() {
147         return max;
148     }
149
150     // Tests
151
//--------------------------------------------------------------------
152

153     /**
154      * <p>Tests whether the specified <code>number</code> occurs within
155      * this range.</p>
156      *
157      * <p><code>null</code> is handled and returns <code>false</code>.</p>
158      *
159      * @param number the number to test, may be <code>null</code>
160      * @return <code>true</code> if the specified number occurs within this range
161      * @throws IllegalArgumentException if the number is of a different type to the range
162      */

163     public boolean containsNumber(Number JavaDoc number) {
164         if (number == null) {
165             return false;
166         }
167         if (number.getClass() != min.getClass()) {
168             throw new IllegalArgumentException JavaDoc("The number must be of the same type as the range numbers");
169         }
170         int compareMin = ((Comparable JavaDoc) min).compareTo(number);
171         int compareMax = ((Comparable JavaDoc) max).compareTo(number);
172         return compareMin <= 0 && compareMax >= 0;
173     }
174
175     // Range tests
176
//--------------------------------------------------------------------
177
// use Range implementations
178

179     // Basics
180
//--------------------------------------------------------------------
181

182     /**
183      * <p>Compares this range to another object to test if they are equal.</p>.
184      *
185      * <p>To be equal, the class, minimum and maximum must be equal.</p>
186      *
187      * @param obj the reference object with which to compare
188      * @return <code>true</code> if this object is equal
189      */

190     public boolean equals(Object JavaDoc obj) {
191         if (obj == this) {
192             return true;
193         }
194         if (obj instanceof NumberRange == false) {
195             return false;
196         }
197         NumberRange range = (NumberRange) obj;
198         return min.equals(range.min) && max.equals(range.max);
199     }
200
201     /**
202      * <p>Gets a hashCode for the range.</p>
203      *
204      * @return a hash code value for this object
205      */

206     public int hashCode() {
207         if (hashCode == 0) {
208             hashCode = 17;
209             hashCode = 37 * hashCode + getClass().hashCode();
210             hashCode = 37 * hashCode + min.hashCode();
211             hashCode = 37 * hashCode + max.hashCode();
212         }
213         return hashCode;
214     }
215
216     /**
217      * <p>Gets the range as a <code>String</code>.</p>
218      *
219      * <p>The format of the String is 'Range[<i>min</i>,<i>max</i>]'.</p>
220      *
221      * @return the <code>String</code> representation of this range
222      */

223     public String JavaDoc toString() {
224         if (toString == null) {
225             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(32);
226             buf.append("Range[");
227             buf.append(min);
228             buf.append(',');
229             buf.append(max);
230             buf.append(']');
231             toString = buf.toString();
232         }
233         return toString;
234     }
235
236 }
237
Popular Tags