001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.lang;
018
019 import org.apache.commons.lang.text.StrBuilder;
020
021 /**
022 * <p>Represents a range of {@link Number} objects.</p>
023 *
024 * <p>This class uses <code>double</code> comparisons. This means that it
025 * is unsuitable for dealing with large <code>Long</code>, <code>BigDecimal</code>
026 * or <code>BigInteger</code> numbers.</p>
027 *
028 * @author Apache Software Foundation
029 * @author <a href="mailto:chrise@esha.com">Christopher Elkins</a>
030 * @since 1.0
031 * @version $Revision: 1057072 $ $Date: 2011-01-10 01:55:57 +0000 (Mon, 10 Jan 2011) $
032 *
033 * @deprecated Use one of the Range classes in org.apache.commons.lang.math.
034 * Class will be removed in Commons Lang 3.0.
035 *
036 */
037 public final class NumberRange {
038
039 /* The minimum number in this range. */
040 private final Number min;
041
042 /* The maximum number in this range. */
043 private final Number max;
044
045
046 /**
047 * <p>Constructs a new <code>NumberRange</code> using
048 * <code>number</code> as both the minimum and maximum in
049 * this range.</p>
050 *
051 * @param num the number to use for this range
052 * @throws NullPointerException if the number is <code>null</code>
053 */
054 public NumberRange(Number num) {
055 if (num == null) {
056 throw new NullPointerException("The number must not be null");
057 }
058
059 this.min = num;
060 this.max = num;
061 }
062
063 /**
064 * <p>Constructs a new <code>NumberRange</code> with the specified
065 * minimum and maximum numbers.</p>
066 *
067 * <p><em>If the maximum is less than the minimum, the range will be constructed
068 * from the minimum value to the minimum value, not what you would expect!.</em></p>
069 *
070 * @param min the minimum number in this range
071 * @param max the maximum number in this range
072 * @throws NullPointerException if either the minimum or maximum number is
073 * <code>null</code>
074 */
075 public NumberRange(Number min, Number max) {
076 if (min == null) {
077 throw new NullPointerException("The minimum value must not be null");
078 } else if (max == null) {
079 throw new NullPointerException("The maximum value must not be null");
080 }
081
082 if (max.doubleValue() < min.doubleValue()) {
083 this.min = this.max = min;
084 } else {
085 this.min = min;
086 this.max = max;
087 }
088 }
089
090 /**
091 * <p>Returns the minimum number in this range.</p>
092 *
093 * @return the minimum number in this range
094 */
095 public Number getMinimum() {
096 return min;
097 }
098
099 /**
100 * <p>Returns the maximum number in this range.</p>
101 *
102 * @return the maximum number in this range
103 */
104 public Number getMaximum() {
105 return max;
106 }
107
108 /**
109 * <p>Tests whether the specified <code>number</code> occurs within
110 * this range using <code>double</code> comparison.</p>
111 *
112 * @param number the number to test
113 * @return <code>true</code> if the specified number occurs within this
114 * range; otherwise, <code>false</code>
115 */
116 public boolean includesNumber(Number number) {
117 if (number == null) {
118 return false;
119 } else {
120 return !(min.doubleValue() > number.doubleValue()) &&
121 !(max.doubleValue() < number.doubleValue());
122 }
123 }
124
125 /**
126 * <p>Tests whether the specified range occurs entirely within this
127 * range using <code>double</code> comparison.</p>
128 *
129 * @param range the range to test
130 * @return <code>true</code> if the specified range occurs entirely within
131 * this range; otherwise, <code>false</code>
132 */
133 public boolean includesRange(NumberRange range) {
134 if (range == null) {
135 return false;
136 } else {
137 return includesNumber(range.min) && includesNumber(range.max);
138 }
139 }
140
141 /**
142 * <p>Tests whether the specified range overlaps with this range
143 * using <code>double</code> comparison.</p>
144 *
145 * @param range the range to test
146 * @return <code>true</code> if the specified range overlaps with this
147 * range; otherwise, <code>false</code>
148 */
149 public boolean overlaps(NumberRange range) {
150 if (range == null) {
151 return false;
152 } else {
153 return range.includesNumber(min) || range.includesNumber(max) ||
154 includesRange(range);
155 }
156 }
157
158 /**
159 * <p>Indicates whether some other <code>Object</code> is
160 * "equal" to this one.</p>
161 *
162 * @param obj the reference object with which to compare
163 * @return <code>true</code> if this object is the same as the obj
164 * argument; <code>false</code> otherwise
165 */
166 public boolean equals(Object obj) {
167 if (obj == this) {
168 return true;
169 } else if (!(obj instanceof NumberRange)) {
170 return false;
171 } else {
172 NumberRange range = (NumberRange)obj;
173 return min.equals(range.min) && max.equals(range.max);
174 }
175 }
176
177 /**
178 * <p>Returns a hash code value for this object.</p>
179 *
180 * @return a hash code value for this object
181 */
182 public int hashCode() {
183 int result = 17;
184 result = 37 * result + min.hashCode();
185 result = 37 * result + max.hashCode();
186 return result;
187 }
188
189 /**
190 * <p>Returns the string representation of this range.</p>
191 *
192 * <p>This string is the string representation of the minimum and
193 * maximum numbers in the range, separated by a hyphen. If a number
194 * is negative, then it is enclosed in parentheses.</p>
195 *
196 * @return the string representation of this range
197 */
198 public String toString() {
199 StrBuilder sb = new StrBuilder();
200
201 if (min.doubleValue() < 0) {
202 sb.append('(')
203 .append(min)
204 .append(')');
205 } else {
206 sb.append(min);
207 }
208
209 sb.append('-');
210
211 if (max.doubleValue() < 0) {
212 sb.append('(')
213 .append(max)
214 .append(')');
215 } else {
216 sb.append(max);
217 }
218
219 return sb.toString();
220 }
221
222 }