1. /* ====================================================================
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowledgement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowledgement may appear in the software itself,
  24. * if and wherever such third-party acknowledgements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Software Foundation.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.commons.lang.math;
  55. import java.io.Serializable;
  56. /**
  57. * <p><code>LongRange</code> represents an inclusive range of <code>long</code>s.</p>
  58. *
  59. * @author Stephen Colebourne
  60. * @since 2.0
  61. * @version $Id: LongRange.java,v 1.5 2003/08/18 02:22:24 bayard Exp $
  62. */
  63. public final class LongRange extends Range implements Serializable {
  64. private static final long serialVersionUID = 71849363892720L;
  65. /**
  66. * The minimum number in this range (inclusive).
  67. */
  68. private final long min;
  69. /**
  70. * The maximum number in this range (inclusive).
  71. */
  72. private final long max;
  73. /**
  74. * Cached output minObject (class is immutable).
  75. */
  76. private transient Long minObject = null;
  77. /**
  78. * Cached output maxObject (class is immutable).
  79. */
  80. private transient Long maxObject = null;
  81. /**
  82. * Cached output hashCode (class is immutable).
  83. */
  84. private transient int hashCode = 0;
  85. /**
  86. * Cached output toString (class is immutable).
  87. */
  88. private transient String toString = null;
  89. /**
  90. * <p>Constructs a new <code>LongRange</code> using the specified
  91. * number as both the minimum and maximum in this range.</p>
  92. *
  93. * @param number the number to use for this range
  94. */
  95. public LongRange(long number) {
  96. super();
  97. this.min = number;
  98. this.max = number;
  99. }
  100. /**
  101. * <p>Constructs a new <code>LongRange</code> using the specified
  102. * number as both the minimum and maximum in this range.</p>
  103. *
  104. * @param number the number to use for this range, must not
  105. * be <code>null</code>
  106. * @throws IllegalArgumentException if the number is <code>null</code>
  107. */
  108. public LongRange(Number number) {
  109. super();
  110. if (number == null) {
  111. throw new IllegalArgumentException("The number must not be null");
  112. }
  113. this.min = number.longValue();
  114. this.max = number.longValue();
  115. if (number instanceof Long) {
  116. this.minObject = (Long) number;
  117. this.maxObject = (Long) number;
  118. }
  119. }
  120. /**
  121. * <p>Constructs a new <code>LongRange</code> with the specified
  122. * minimum and maximum numbers (both inclusive).</p>
  123. *
  124. * <p>The arguments may be passed in the order (min,max) or (max,min). The
  125. * getMinimum and getMaximum methods will return the correct values.</p>
  126. *
  127. * @param number1 first number that defines the edge of the range, inclusive
  128. * @param number2 second number that defines the edge of the range, inclusive
  129. */
  130. public LongRange(long number1, long number2) {
  131. super();
  132. if (number2 < number1) {
  133. this.min = number2;
  134. this.max = number1;
  135. } else {
  136. this.min = number1;
  137. this.max = number2;
  138. }
  139. }
  140. /**
  141. * <p>Constructs a new <code>LongRange</code> with the specified
  142. * minimum and maximum numbers (both inclusive).</p>
  143. *
  144. * <p>The arguments may be passed in the order (min,max) or (max,min). The
  145. * getMinimum and getMaximum methods will return the correct values.</p>
  146. *
  147. * @param number1 first number that defines the edge of the range, inclusive
  148. * @param number2 second number that defines the edge of the range, inclusive
  149. * @throws IllegalArgumentException if either number is <code>null</code>
  150. */
  151. public LongRange(Number number1, Number number2) {
  152. super();
  153. if (number1 == null || number2 == null) {
  154. throw new IllegalArgumentException("The numbers must not be null");
  155. }
  156. long number1val = number1.longValue();
  157. long number2val = number2.longValue();
  158. if (number2val < number1val) {
  159. this.min = number2val;
  160. this.max = number1val;
  161. if (number2 instanceof Long) {
  162. this.minObject = (Long) number2;
  163. }
  164. if (number1 instanceof Long) {
  165. this.maxObject = (Long) number1;
  166. }
  167. } else {
  168. this.min = number1val;
  169. this.max = number2val;
  170. if (number1 instanceof Long) {
  171. this.minObject = (Long) number1;
  172. }
  173. if (number2 instanceof Long) {
  174. this.maxObject = (Long) number2;
  175. }
  176. }
  177. }
  178. // Accessors
  179. //--------------------------------------------------------------------
  180. /**
  181. * <p>Returns the minimum number in this range.</p>
  182. *
  183. * @return the minimum number in this range
  184. */
  185. public Number getMinimumNumber() {
  186. if (minObject == null) {
  187. minObject = new Long(min);
  188. }
  189. return minObject;
  190. }
  191. /**
  192. * <p>Gets the minimum number in this range as a <code>long</code>.</p>
  193. *
  194. * @return the minimum number in this range
  195. */
  196. public long getMinimumLong() {
  197. return min;
  198. }
  199. /**
  200. * <p>Gets the minimum number in this range as a <code>int</code>.</p>
  201. *
  202. * <p>This conversion can lose information for large values.</p>
  203. *
  204. * @return the minimum number in this range
  205. */
  206. public int getMinimumInteger() {
  207. return (int) min;
  208. }
  209. /**
  210. * <p>Gets the minimum number in this range as a <code>double</code>.</p>
  211. *
  212. * <p>This conversion can lose information for large values.</p>
  213. *
  214. * @return the minimum number in this range
  215. */
  216. public double getMinimumDouble() {
  217. return min;
  218. }
  219. /**
  220. * <p>Gets the minimum number in this range as a <code>float</code>.</p>
  221. *
  222. * <p>This conversion can lose information for large values.</p>
  223. *
  224. * @return the minimum number in this range
  225. */
  226. public float getMinimumFloat() {
  227. return min;
  228. }
  229. /**
  230. * <p>Returns the maximum number in this range.</p>
  231. *
  232. * @return the maximum number in this range
  233. */
  234. public Number getMaximumNumber() {
  235. if (maxObject == null) {
  236. maxObject = new Long(max);
  237. }
  238. return maxObject;
  239. }
  240. /**
  241. * <p>Gets the maximum number in this range as a <code>long</code>.</p>
  242. *
  243. * @return the maximum number in this range
  244. */
  245. public long getMaximumLong() {
  246. return max;
  247. }
  248. /**
  249. * <p>Gets the maximum number in this range as a <code>int</code>.</p>
  250. *
  251. * <p>This conversion can lose information for large values.</p>
  252. */
  253. public int getMaximumInteger() {
  254. return (int) max;
  255. }
  256. /**
  257. * <p>Gets the maximum number in this range as a <code>double</code>.</p>
  258. *
  259. * <p>This conversion can lose information for large values.</p>
  260. */
  261. public double getMaximumDouble() {
  262. return max;
  263. }
  264. /**
  265. * <p>Gets the maximum number in this range as a <code>float</code>.</p>
  266. *
  267. * <p>This conversion can lose information for large values.</p>
  268. */
  269. public float getMaximumFloat() {
  270. return max;
  271. }
  272. // Tests
  273. //--------------------------------------------------------------------
  274. /**
  275. * <p>Tests whether the specified <code>number</code> occurs within
  276. * this range using <code>long</code> comparison.</p>
  277. *
  278. * <p><code>null</code> is handled and returns <code>false</code>.</p>
  279. *
  280. * @param number the number to test, may be <code>null</code>
  281. * @return <code>true</code> if the specified number occurs within this range
  282. */
  283. public boolean containsNumber(Number number) {
  284. if (number == null) {
  285. return false;
  286. }
  287. return containsLong(number.longValue());
  288. }
  289. /**
  290. * <p>Tests whether the specified <code>long</code> occurs within
  291. * this range using <code>long</code> comparison.</p>
  292. *
  293. * <p>This implementation overrides the superclass for performance as it is
  294. * the most common case.</p>
  295. *
  296. * @param value the long to test
  297. * @return <code>true</code> if the specified number occurs within this
  298. * range by <code>long</code> comparison
  299. */
  300. public boolean containsLong(long value) {
  301. return (value >= min && value <= max);
  302. }
  303. // Range tests
  304. //--------------------------------------------------------------------
  305. /**
  306. * <p>Tests whether the specified range occurs entirely within this range
  307. * using <code>long</code> comparison.</p>
  308. *
  309. * <p><code>null</code> is handled and returns <code>false</code>.</p>
  310. *
  311. * @param range the range to test, may be <code>null</code>
  312. * @return <code>true</code> if the specified range occurs entirely within this range
  313. * @throws IllegalArgumentException if the range is not of this type
  314. */
  315. public boolean containsRange(Range range) {
  316. if (range == null) {
  317. return false;
  318. }
  319. return containsLong(range.getMinimumLong()) &&
  320. containsLong(range.getMaximumLong());
  321. }
  322. /**
  323. * <p>Tests whether the specified range overlaps with this range
  324. * using <code>long</code> comparison.</p>
  325. *
  326. * <p><code>null</code> is handled and returns <code>false</code>.</p>
  327. *
  328. * @param range the range to test, may be <code>null</code>
  329. * @return <code>true</code> if the specified range overlaps with this range
  330. */
  331. public boolean overlapsRange(Range range) {
  332. if (range == null) {
  333. return false;
  334. }
  335. return range.containsLong(min) ||
  336. range.containsLong(max) ||
  337. containsLong(range.getMinimumLong());
  338. }
  339. // Basics
  340. //--------------------------------------------------------------------
  341. /**
  342. * <p>Compares this range to another object to test if they are equal.</p>.
  343. *
  344. * <p>To be equal, the class, minimum and maximum must be equal.</p>
  345. *
  346. * @param obj the reference object with which to compare
  347. * @return <code>true</code> if this object is equal
  348. */
  349. public boolean equals(Object obj) {
  350. if (obj == this) {
  351. return true;
  352. }
  353. if (obj instanceof LongRange == false) {
  354. return false;
  355. }
  356. LongRange range = (LongRange) obj;
  357. return (min == range.min && max == range.max);
  358. }
  359. /**
  360. * <p>Gets a hashCode for the range.</p>
  361. *
  362. * @return a hash code value for this object
  363. */
  364. public int hashCode() {
  365. if (hashCode == 0) {
  366. hashCode = 17;
  367. hashCode = 37 * hashCode + getClass().hashCode();
  368. hashCode = 37 * hashCode + ((int) (min ^ (min >> 32)));
  369. hashCode = 37 * hashCode + ((int) (max ^ (max >> 32)));
  370. }
  371. return hashCode;
  372. }
  373. /**
  374. * <p>Gets the range as a <code>String</code>.</p>
  375. *
  376. * <p>The format of the String is 'Range[<i>min</i>,<i>max</i>]'.</p>
  377. *
  378. * @return the <code>String</code> representation of this range
  379. */
  380. public String toString() {
  381. if (toString == null) {
  382. StringBuffer buf = new StringBuffer(32);
  383. buf.append("Range[");
  384. buf.append(min);
  385. buf.append(',');
  386. buf.append(max);
  387. buf.append(']');
  388. toString = buf.toString();
  389. }
  390. return toString;
  391. }
  392. }