Java/Collections Data Structure/Range

Материал из Java эксперт
Версия от 10:25, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Byte Range

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

* @version $Id: ByteRange.java 587751 2007-10-24 02:41:36Z vgritsenko $
*/

final public class ByteRange {

   private final long start;
   private final long end;
   
   public ByteRange(long start, long end) {
       this.start = start;
       this.end = end;
   }
   
   public ByteRange(String string) throws NumberFormatException {
       string = string.trim();
       int dashPos = string.indexOf("-");
       int length = string.length();
       if (string.indexOf(",") != -1) {
           throw new NumberFormatException("Simple ByteRange String contains a comma.");
       }
       if (dashPos > 0) {
           this.start = Integer.parseInt(string.substring(0, dashPos));
       } else {
           this.start = Long.MIN_VALUE;
       }
       if (dashPos < length - 1) {
           this.end = Integer.parseInt(string.substring(dashPos + 1, length));
       } else {
           this.end = Long.MAX_VALUE;
       }
       if (this.start > this.end) {
           throw new NumberFormatException("Start value is greater than end value.");
       }
   }
   
   public long getStart() {
       return this.start;
   }
   
   public long getEnd() {
       return this.end;
   }
   
   public long length() {
       return this.end - this.start + 1;
   }
   
   public ByteRange intersection(ByteRange range) {
       if (range.end < this.start || this.end < range.start) {
           return null;
       } else {
           long start = (this.start > range.start) ? this.start : range.start;
           long end = (this.end < range.end) ? this.end : range.end;
           return new ByteRange(start, end);
       }
   }
   public String toString() {
       return this.start + "-" + this.end;
   }
   

}


 </source>
   
  
 
  



Finds the value in the range (start,limit) of the largest element (rank) where the count of all smaller elements in that range is less than or equals target.

   <source lang="java">
   
    

/* Copyright (c) 2001-2009, The HSQL Development Group

* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**

* Collection of routines for counting the distribution of the values
* in an int[] array.
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 1.7.2
* @since 1.7.2
*/

public class ArrayCounter {

   /**
    * Returns an int[] array of length segments containing the distribution
    * count of the elements in unsorted int[] array with values between min
* and max (range). Values outside the min-max range are ignored

* * A usage example is determining the count of people of each age group * in a large int[] array containing the age of each person. Called with * (array, 16,0,79), it will return an int[16] with the first element * the count of people aged 0-4, the second element the count of those * aged 5-9, and so on. People above the age of 79 are excluded. If the * range is not a multiple of segments, the last segment will be cover a * smaller sub-range than the rest. * */ public static int[] countSegments(int[] array, int elements, int segments, int start, int limit) { int[] counts = new int[segments]; long interval = calcInterval(segments, start, limit); int index = 0; int element = 0; if (interval <= 0) { return counts; } for (int i = 0; i < elements; i++) { element = array[i]; if (element < start || element >= limit) { continue; } index = (int) ((element - start) / interval); counts[index]++; } return counts; } /** * With an unsorted int[] array and with target a positive integer in the * range (1,array.length), finds the value in the range (start,limit) of the * largest element (rank) where the count of all smaller elements in that * range is less than or equals target. Parameter margin indicates the * margin of error in target<p> * * In statistics, this can be used to calculate a median or quadrile value. * A usage example applied to an array of age values is to determine * the maximum age of a given number of people. With the example array * given in countSegments, rank(array, c, 6000, 18, 65, 0) will return an age * value between 18-64 (inclusive) and the count of all people aged between * 18 and the returned value(exclusive) will be less than or equal 6000. * */ public static int rank(int[] array, int elements, int target, int start, int limit, int margin) { final int segments = 256; int elementCount = 0; int currentLimit = limit; for (;;) { long interval = calcInterval(segments, start, currentLimit); int[] counts = countSegments(array, elements, segments, start, currentLimit); for (int i = 0; i < counts.length; i++) { if (elementCount + counts[i] < target) { elementCount += counts[i]; start += interval; } else { break; } } if (elementCount + margin >= target) { return start; } if (interval <= 1) { return start; } currentLimit = start + interval < limit ? (int) (start + interval)  : limit; } } /** * Helper method to calculate the span of the sub-interval. Simply returns * the cieling of ((limit - start) / segments) and accounts for invalid * start and limit combinations. */ static long calcInterval(int segments, int start, int limit) { long range = limit - start; if (range < 0) { return 0; } int partSegment = (range % segments) == 0 ? 0  : 1; return (range / segments) + partSegment; } } </source>

IntRange represents an inclusive range of ints.

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.Serializable; /**

* <p>IntRange represents an inclusive range of ints.

*
* @author Stephen Colebourne
* @since 2.0
* @version $Id: IntRange.java 594398 2007-11-13 02:43:10Z bayard $
*/

public final class IntRange extends Range implements Serializable {

   /**
    * Required for serialization support.
    * 
    * @see java.io.Serializable
    */
   private static final long serialVersionUID = 71849363892730L;
   /**
    * The minimum number in this range (inclusive).
    */
   private final int min;
   /**
    * The maximum number in this range (inclusive).
    */
   private final int max;
   
   /**
    * Cached output minObject (class is immutable).
    */
   private transient Integer minObject = null;
   /**
    * Cached output maxObject (class is immutable).
    */
   private transient Integer maxObject = null;
   /**
    * Cached output hashCode (class is immutable).
    */
   private transient int hashCode = 0;
   /**
    * Cached output toString (class is immutable).
    */
   private transient String toString = null;
   
   /**
*

Constructs a new IntRange using the specified * number as both the minimum and maximum in this range.

    *
    * @param number  the number to use for this range
    */
   public IntRange(int number) {
       super();
       this.min = number;
       this.max = number;
   }
   /**
*

Constructs a new IntRange using the specified * number as both the minimum and maximum in this range.

    *
    * @param number  the number to use for this range, must not be null
    * @throws IllegalArgumentException if the number is null
    */
   public IntRange(Number number) {
       super();
       if (number == null) {
           throw new IllegalArgumentException("The number must not be null");
       }
       this.min = number.intValue();
       this.max = number.intValue();
       if (number instanceof Integer) {
           this.minObject = (Integer) number;
           this.maxObject = (Integer) number;
       }
   }
   /**
*

Constructs a new IntRange with the specified * minimum and maximum numbers (both inclusive).

    * 
*

The arguments may be passed in the order (min,max) or (max,min). The * getMinimum and getMaximum methods will return the correct values.

    * 
    * @param number1  first number that defines the edge of the range, inclusive
    * @param number2  second number that defines the edge of the range, inclusive
    */
   public IntRange(int number1, int number2) {
       super();
       if (number2 < number1) {
           this.min = number2;
           this.max = number1;
       } else {
           this.min = number1;
           this.max = number2;
       }
   }
   /**
*

Constructs a new IntRange with the specified * minimum and maximum numbers (both inclusive).

    * 
*

The arguments may be passed in the order (min,max) or (max,min). The * getMinimum and getMaximum methods will return the correct values.

    *
    * @param number1  first number that defines the edge of the range, inclusive
    * @param number2  second number that defines the edge of the range, inclusive
    * @throws IllegalArgumentException if either number is null
    */
   public IntRange(Number number1, Number number2) {
       super();
       if (number1 == null || number2 == null) {
           throw new IllegalArgumentException("The numbers must not be null");
       }
       int number1val = number1.intValue();
       int number2val = number2.intValue();
       if (number2val < number1val) {
           this.min = number2val;
           this.max = number1val;
           if (number2 instanceof Integer) {
               this.minObject = (Integer) number2;
           }
           if (number1 instanceof Integer) {
               this.maxObject = (Integer) number1;
           }
       } else {
           this.min = number1val;
           this.max = number2val;
           if (number1 instanceof Integer) {
               this.minObject = (Integer) number1;
           }
           if (number2 instanceof Integer) {
               this.maxObject = (Integer) number2;
           }
       }
   }
   // Accessors
   //--------------------------------------------------------------------
   /**
*

Returns the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public Number getMinimumNumber() {
       if (minObject == null) {
           minObject = new Integer(min);            
       }
       return minObject;
   }
   /**
*

Gets the minimum number in this range as a long.

    *
    * @return the minimum number in this range
    */
   public long getMinimumLong() {
       return min;
   }
   /**
*

Gets the minimum number in this range as a int.

    *
    * @return the minimum number in this range
    */
   public int getMinimumInteger() {
       return min;
   }
   /**
*

Gets the minimum number in this range as a double.

    *
    * @return the minimum number in this range
    */
   public double getMinimumDouble() {
       return min;
   }
   /**
*

Gets the minimum number in this range as a float.

    *
    * @return the minimum number in this range
    */
   public float getMinimumFloat() {
       return min;
   }
   /**
*

Returns the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public Number getMaximumNumber() {
       if (maxObject == null) {
           maxObject = new Integer(max);            
       }
       return maxObject;
   }
   /**
*

Gets the maximum number in this range as a long.

    *
    * @return the maximum number in this range
    */
   public long getMaximumLong() {
       return max;
   }
   /**
*

Gets the maximum number in this range as a int.

    *
    * @return the maximum number in this range
    */
   public int getMaximumInteger() {
       return max;
   }
   /**
*

Gets the maximum number in this range as a double.

    *
    * @return the maximum number in this range
    */
   public double getMaximumDouble() {
       return max;
   }
   /**
*

Gets the maximum number in this range as a float.

    *
    * @return the maximum number in this range
    */
   public float getMaximumFloat() {
       return max;
   }
   // Tests
   //--------------------------------------------------------------------
   
   /**
*

Tests whether the specified number occurs within * this range using int comparison.

    * 
*

null is handled and returns false.

    *
    * @param number  the number to test, may be null
    * @return true if the specified number occurs within this range
    */
   public boolean containsNumber(Number number) {
       if (number == null) {
           return false;
       }
       return containsInteger(number.intValue());
   }
   /**
*

Tests whether the specified int occurs within * this range using int comparison.

    * 
*

This implementation overrides the superclass for performance as it is * the most common case.

    * 
    * @param value  the int to test
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(int value) {
       return value >= min && value <= max;
   }
   // Range tests
   //--------------------------------------------------------------------
   /**
*

Tests whether the specified range occurs entirely within this range * using int comparison.

    * 
*

null is handled and returns false.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range occurs entirely within this range
    * @throws IllegalArgumentException if the range is not of this type
    */
   public boolean containsRange(Range range) {
       if (range == null) {
           return false;
       }
       return containsInteger(range.getMinimumInteger()) &&
              containsInteger(range.getMaximumInteger());
   }
   /**
*

Tests whether the specified range overlaps with this range * using int comparison.

    * 
*

null is handled and returns false.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range overlaps with this range
    */
   public boolean overlapsRange(Range range) {
       if (range == null) {
           return false;
       }
       return range.containsInteger(min) ||
              range.containsInteger(max) || 
              containsInteger(range.getMinimumInteger());
   }
   // Basics
   //--------------------------------------------------------------------
   /**
*

Compares this range to another object to test if they are equal.

.
    * 
*

To be equal, the class, minimum and maximum must be equal.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is equal
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       }
       if (obj instanceof IntRange == false) {
           return false;
       }
       IntRange range = (IntRange) obj;
       return min == range.min && max == range.max;
   }
   /**
*

Gets a hashCode for the range.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       if (hashCode == 0) {
           hashCode = 17;
           hashCode = 37 * hashCode + getClass().hashCode();
           hashCode = 37 * hashCode + min;
           hashCode = 37 * hashCode + max;
       }
       return hashCode;
   }
   /**
*

Gets the range as a String.

    *
*

The format of the String is "Range[min,max]".

    *
    * @return the String representation of this range
    */
   public String toString() {
       if (toString == null) {
           StringBuffer buf = new StringBuffer(32);
           buf.append("Range[");
           buf.append(min);
           buf.append(",");
           buf.append(max);
           buf.append("]");
           toString = buf.toString();
       }
       return toString;
   }
   /**
*

Returns an array containing all the integer values in the range.

    *
    * @return the int[] representation of this range
    * @since 2.4
    */
   public int[] toArray() {
       int[] array = new int[max - min + 1];
       for (int i = 0; i < array.length; i++) {
           array[i] = min + i;
       }
       return array;
   }

} /*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

*

Range represents a range of numbers of the same type.

* 
*

Specific subclasses hold the range values as different types. Each * subclass should be immutable and {@link java.io.Serializable Serializable} * if possible.

*
* @author Stephen Colebourne
* @since 2.0
* @version $Id: Range.java 437554 2006-08-28 06:21:41Z bayard $
*/

abstract class Range {

   /**
*

Constructs a new range.

    */
   public Range() {
       super();
   }
   // Accessors
   //--------------------------------------------------------------------
   /**
*

Gets the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public abstract Number getMinimumNumber();
   /**
*

Gets the minimum number in this range as a long.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public long getMinimumLong() {
       return getMinimumNumber().longValue();
   }
   /**
*

Gets the minimum number in this range as a int.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public int getMinimumInteger() {
       return getMinimumNumber().intValue();
   }
   /**
*

Gets the minimum number in this range as a double.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public double getMinimumDouble() {
       return getMinimumNumber().doubleValue();
   }
   /**
*

Gets the minimum number in this range as a float.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public float getMinimumFloat() {
       return getMinimumNumber().floatValue();
   }
   /**
*

Gets the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public abstract Number getMaximumNumber();
   /**
*

Gets the maximum number in this range as a long.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public long getMaximumLong() {
       return getMaximumNumber().longValue();
   }
   /**
*

Gets the maximum number in this range as a int.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public int getMaximumInteger() {
       return getMaximumNumber().intValue();
   }
   /**
*

Gets the maximum number in this range as a double.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public double getMaximumDouble() {
       return getMaximumNumber().doubleValue();
   }
   /**
*

Gets the maximum number in this range as a float.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public float getMaximumFloat() {
       return getMaximumNumber().floatValue();
   }
   // Include tests
   //--------------------------------------------------------------------
   
   /**
*

Tests whether the specified Number occurs within * this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    *
    * @param number  the number to test, may be null
    * @return true if the specified number occurs within this range
    * @throws IllegalArgumentException if the Number cannot be compared
    */
   public abstract boolean containsNumber(Number number);
   /**
*

Tests whether the specified Number occurs within * this range using long comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsLong(long)} method.

    *
    * @param value  the long to test, may be null
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(Number value) {
       if (value == null) {
           return false;
       }
       return containsLong(value.longValue());
   }
   /**
*

Tests whether the specified long occurs within * this range using long comparison.

    * 
*

This implementation uses the {@link #getMinimumLong()} and * {@link #getMaximumLong()} methods and should be good for most uses.

    * 
    * @param value  the long to test
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(long value) {
       return value >= getMinimumLong() && value <= getMaximumLong();
   }
   /**
*

Tests whether the specified Number occurs within * this range using int comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsInteger(int)} method.

    *
    * @param value  the integer to test, may be null
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(Number value) {
       if (value == null) {
           return false;
       }
       return containsInteger(value.intValue());
   }
   /**
*

Tests whether the specified int occurs within * this range using int comparison.

    * 
*

This implementation uses the {@link #getMinimumInteger()} and * {@link #getMaximumInteger()} methods and should be good for most uses.

    * 
    * @param value  the int to test
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(int value) {
       return value >= getMinimumInteger() && value <= getMaximumInteger();
   }
   /**
*

Tests whether the specified Number occurs within * this range using double comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsDouble(double)} method.

    *
    * @param value  the double to test, may be null
    * @return true if the specified number occurs within this
    *  range by double comparison
    */
   public boolean containsDouble(Number value) {
       if (value == null) {
           return false;
       }
       return containsDouble(value.doubleValue());
   }
   /**
*

Tests whether the specified double occurs within * this range using double comparison.

    * 
*

This implementation uses the {@link #getMinimumDouble()} and * {@link #getMaximumDouble()} methods and should be good for most uses.

    * 
    * @param value  the double to test
    * @return true if the specified number occurs within this
    *  range by double comparison
    */
   public boolean containsDouble(double value) {
       int compareMin = compare(getMinimumDouble(), value);
       int compareMax = compare(getMaximumDouble(), value);
       return compareMin <= 0 && compareMax >= 0;
   }
   /**
*

Tests whether the specified Number occurs within * this range using float comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsFloat(float)} method.

    *
    * @param value  the float to test, may be null
    * @return true if the specified number occurs within this
    *  range by float comparison
    */
   public boolean containsFloat(Number value) {
       if (value == null) {
           return false;
       }
       return containsFloat(value.floatValue());
   }
   /**
*

Tests whether the specified float occurs within * this range using float comparison.

    * 
*

This implementation uses the {@link #getMinimumFloat()} and * {@link #getMaximumFloat()} methods and should be good for most uses.

    * 
    * @param value  the float to test
    * @return true if the specified number occurs within this
    *  range by float comparison
    */
   public boolean containsFloat(float value) {
       int compareMin = compare(getMinimumFloat(), value);
       int compareMax = compare(getMaximumFloat(), value);
       return compareMin <= 0 && compareMax >= 0;
   }
   // Range tests
   //--------------------------------------------------------------------
   /**
*

Tests whether the specified range occurs entirely within this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation uses the {@link #containsNumber(Number)} method. * Subclasses may be able to optimise this.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range occurs entirely within
    *  this range; otherwise, false
    * @throws IllegalArgumentException if the Range cannot be compared
    */
   public boolean containsRange(Range range) {
       if (range == null) {
           return false;
       }
       return containsNumber(range.getMinimumNumber()) 
           && containsNumber(range.getMaximumNumber());
   }
   /**
*

Tests whether the specified range overlaps with this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation uses the {@link #containsNumber(Number)} and * {@link #containsRange(Range)} methods. * Subclasses may be able to optimise this.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range overlaps with this
    *  range; otherwise, false
    * @throws IllegalArgumentException if the Range cannot be compared
    */
   public boolean overlapsRange(Range range) {
       if (range == null) {
           return false;
       }
       return range.containsNumber(getMinimumNumber())
           || range.containsNumber(getMaximumNumber())
           || containsNumber(range.getMinimumNumber());
   }
   // Basics
   //--------------------------------------------------------------------
   /**
*

Compares this range to another object to test if they are equal.

.
    * 
*

To be equal, the class, minimum and maximum must be equal.

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is equal
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       } else if (obj == null || obj.getClass() != getClass()) {
           return false;
       } else {
           Range range = (Range) obj;
           return getMinimumNumber().equals(range.getMinimumNumber()) &&
                  getMaximumNumber().equals(range.getMaximumNumber());
       }
   }
   /**
*

Gets a hashCode for the range.

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       int result = 17;
       result = 37 * result + getClass().hashCode();
       result = 37 * result + getMinimumNumber().hashCode();
       result = 37 * result + getMaximumNumber().hashCode();
       return result;
   }
   /**
*

Gets the range as a String.

    *
*

The format of the String is "Range[min,max]".

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @return the String representation of this range
    */
   public String toString() {
       StringBuffer buf = new StringBuffer(32);
       buf.append("Range[");
       buf.append(getMinimumNumber());
       buf.append(",");
       buf.append(getMaximumNumber());
       buf.append("]");
       return buf.toString();
   }
   /**
*

Compares two doubles for order.

    *
*

This method is more comprehensive than the standard Java greater * than, less than and equals operators.

*
    *
  • It returns -1 if the first value is less than the second.
  • *
  • It returns +1 if the first value is greater than the second.
  • *
  • It returns 0 if the values are equal.
  • *
    *
*

* The ordering is as follows, largest to smallest: *

    *
  • NaN *
  • Positive infinity *
  • Maximum double *
  • Normal positive numbers *
  • +0.0 *
  • -0.0 *
  • Normal negative numbers *
  • Minimum double (-Double.MAX_VALUE) *
  • Negative infinity *
*

    *
*

Comparing NaN with NaN will * return 0.

    * 
    * @param lhs  the first double
    * @param rhs  the second double
    * @return -1 if lhs is less, +1 if greater,
    *  0 if equal to rhs
    */
   public static int compare(double lhs, double rhs) {
       if (lhs < rhs) {
           return -1;
       }
       if (lhs > rhs) {
           return +1;
       }
       // Need to compare bits to handle 0.0 == -0.0 being true
       // compare should put -0.0 < +0.0
       // Two NaNs are also == for compare purposes
       // where NaN == NaN is false
       long lhsBits = Double.doubleToLongBits(lhs);
       long rhsBits = Double.doubleToLongBits(rhs);
       if (lhsBits == rhsBits) {
           return 0;
       }
       // Something exotic! A comparison to NaN or 0.0 vs -0.0
       // Fortunately NaN"s long is > than everything else
       // Also negzeros bits < poszero
       // NAN: 9221120237041090560
       // MAX: 9218868437227405311
       // NEGZERO: -9223372036854775808
       if (lhsBits < rhsBits) {
           return -1;
       } else {
           return +1;
       }
   }
   
   /**
*

Compares two floats for order.

    *
*

This method is more comprehensive than the standard Java greater than, * less than and equals operators.

*
    *
  • It returns -1 if the first value is less than the second. *
  • It returns +1 if the first value is greater than the second. *
  • It returns 0 if the values are equal. *
    *
*

The ordering is as follows, largest to smallest: *

    *
  • NaN *
  • Positive infinity *
  • Maximum float *
  • Normal positive numbers *
  • +0.0 *
  • -0.0 *
  • Normal negative numbers *
  • Minimum float (-Float.MAX_VALUE) *
  • Negative infinity *
    *
    * <p>Comparing NaN with NaN will return
* 0.

    * 
    * @param lhs  the first float
    * @param rhs  the second float
    * @return -1 if lhs is less, +1 if greater,
    *  0 if equal to rhs
    */
   public static int compare(float lhs, float rhs) {
       if (lhs < rhs) {
           return -1;
       }
       if (lhs > rhs) {
           return +1;
       }
       //Need to compare bits to handle 0.0 == -0.0 being true
       // compare should put -0.0 < +0.0
       // Two NaNs are also == for compare purposes
       // where NaN == NaN is false
       int lhsBits = Float.floatToIntBits(lhs);
       int rhsBits = Float.floatToIntBits(rhs);
       if (lhsBits == rhsBits) {
           return 0;
       }
       //Something exotic! A comparison to NaN or 0.0 vs -0.0
       //Fortunately NaN"s int is > than everything else
       //Also negzeros bits < poszero
       //NAN: 2143289344
       //MAX: 2139095039
       //NEGZERO: -2147483648
       if (lhsBits < rhsBits) {
           return -1;
       } else {
           return +1;
       }
   }

}


 </source>
   
  
 
  



LongRange represents an inclusive range of longs.

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.Serializable; /**

*

LongRange represents an inclusive range of longs.

*
* @author Stephen Colebourne
* @since 2.0
* @version $Id: LongRange.java 594398 2007-11-13 02:43:10Z bayard $
*/

public final class LongRange extends Range implements Serializable {

   /**
    * Required for serialization support.
    * 
    * @see java.io.Serializable
    */
   private static final long serialVersionUID = 71849363892720L;
   /**
    * The minimum number in this range (inclusive).
    */
   private final long min;
   /**
    * The maximum number in this range (inclusive).
    */
   private final long max;
   
   /**
    * Cached output minObject (class is immutable).
    */
   private transient Long minObject = null;
   /**
    * Cached output maxObject (class is immutable).
    */
   private transient Long maxObject = null;
   /**
    * Cached output hashCode (class is immutable).
    */
   private transient int hashCode = 0;
   /**
    * Cached output toString (class is immutable).
    */
   private transient String toString = null;
   
   /**
*

Constructs a new LongRange using the specified * number as both the minimum and maximum in this range.

    *
    * @param number  the number to use for this range
    */
   public LongRange(long number) {
       super();
       this.min = number;
       this.max = number;
   }
   /**
*

Constructs a new LongRange using the specified * number as both the minimum and maximum in this range.

    *
    * @param number  the number to use for this range, must not
    *  be null
    * @throws IllegalArgumentException if the number is null
    */
   public LongRange(Number number) {
       super();
       if (number == null) {
           throw new IllegalArgumentException("The number must not be null");
       }
       this.min = number.longValue();
       this.max = number.longValue();
       if (number instanceof Long) {
           this.minObject = (Long) number;
           this.maxObject = (Long) number;
       }
   }
   /**
*

Constructs a new LongRange with the specified * minimum and maximum numbers (both inclusive).

    * 
*

The arguments may be passed in the order (min,max) or (max,min). The * getMinimum and getMaximum methods will return the correct values.

    * 
    * @param number1  first number that defines the edge of the range, inclusive
    * @param number2  second number that defines the edge of the range, inclusive
    */
   public LongRange(long number1, long number2) {
       super();
       if (number2 < number1) {
           this.min = number2;
           this.max = number1;
       } else {
           this.min = number1;
           this.max = number2;
       }
   }
   /**
*

Constructs a new LongRange with the specified * minimum and maximum numbers (both inclusive).

    * 
*

The arguments may be passed in the order (min,max) or (max,min). The * getMinimum and getMaximum methods will return the correct values.

    *
    * @param number1  first number that defines the edge of the range, inclusive
    * @param number2  second number that defines the edge of the range, inclusive
    * @throws IllegalArgumentException if either number is null
    */
   public LongRange(Number number1, Number number2) {
       super();
       if (number1 == null || number2 == null) {
           throw new IllegalArgumentException("The numbers must not be null");
       }
       long number1val = number1.longValue();
       long number2val = number2.longValue();
       if (number2val < number1val) {
           this.min = number2val;
           this.max = number1val;
           if (number2 instanceof Long) {
               this.minObject = (Long) number2;
           }
           if (number1 instanceof Long) {
               this.maxObject = (Long) number1;
           }
       } else {
           this.min = number1val;
           this.max = number2val;
           if (number1 instanceof Long) {
               this.minObject = (Long) number1;
           }
           if (number2 instanceof Long) {
               this.maxObject = (Long) number2;
           }
       }
   }
   // Accessors
   //--------------------------------------------------------------------
   /**
*

Returns the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public Number getMinimumNumber() {
       if (minObject == null) {
           minObject = new Long(min);            
       }
       return minObject;
   }
   /**
*

Gets the minimum number in this range as a long.

    *
    * @return the minimum number in this range
    */
   public long getMinimumLong() {
       return min;
   }
   /**
*

Gets the minimum number in this range as a int.

    * 
*

This conversion can lose information for large values.

    *
    * @return the minimum number in this range
    */
   public int getMinimumInteger() {
       return (int) min;
   }
   /**
*

Gets the minimum number in this range as a double.

    * 
*

This conversion can lose information for large values.

    *
    * @return the minimum number in this range
    */
   public double getMinimumDouble() {
       return min;
   }
   /**
*

Gets the minimum number in this range as a float.

    * 
*

This conversion can lose information for large values.

    *
    * @return the minimum number in this range
    */
   public float getMinimumFloat() {
       return min;
   }
   /**
*

Returns the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public Number getMaximumNumber() {
       if (maxObject == null) {
           maxObject = new Long(max);            
       }
       return maxObject;
   }
   /**
*

Gets the maximum number in this range as a long.

    *
    * @return the maximum number in this range
    */
   public long getMaximumLong() {
       return max;
   }
   /**
*

Gets the maximum number in this range cast to an int.

    * 
*

This conversion can lose information for large values.

    * 
    * @return the maximum number in this range cast to an int.
    */
   public int getMaximumInteger() {
       return (int) max;
   }
   /**
*

Gets the maximum number in this range as a double.

    * 
*

This conversion can lose information for large values.

    * 
    * @return The maximum number in this range as a double.
    */
   public double getMaximumDouble() {
       return max;
   }
   /**
*

Gets the maximum number in this range as a float.

    * 
*

This conversion can lose information for large values.

    * 
    * @return The maximum number in this range as a float.
    */
   public float getMaximumFloat() {
       return max;
   }
   // Tests
   //--------------------------------------------------------------------
   
   /**
*

Tests whether the specified number occurs within * this range using long comparison.

    * 
*

null is handled and returns false.

    *
    * @param number  the number to test, may be null
    * @return true if the specified number occurs within this range
    */
   public boolean containsNumber(Number number) {
       if (number == null) {
           return false;
       }
       return containsLong(number.longValue());
   }
   /**
*

Tests whether the specified long occurs within * this range using long comparison.

    * 
*

This implementation overrides the superclass for performance as it is * the most common case.

    * 
    * @param value  the long to test
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(long value) {
       return value >= min && value <= max;
   }
   // Range tests
   //--------------------------------------------------------------------
   /**
*

Tests whether the specified range occurs entirely within this range * using long comparison.

    * 
*

null is handled and returns false.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range occurs entirely within this range
    * @throws IllegalArgumentException if the range is not of this type
    */
   public boolean containsRange(Range range) {
       if (range == null) {
           return false;
       }
       return containsLong(range.getMinimumLong()) &&
              containsLong(range.getMaximumLong());
   }
   /**
*

Tests whether the specified range overlaps with this range * using long comparison.

    * 
*

null is handled and returns false.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range overlaps with this range
    */
   public boolean overlapsRange(Range range) {
       if (range == null) {
           return false;
       }
       return range.containsLong(min) ||
              range.containsLong(max) || 
              containsLong(range.getMinimumLong());
   }
   // Basics
   //--------------------------------------------------------------------
   /**
*

Compares this range to another object to test if they are equal.

.
    * 
*

To be equal, the class, minimum and maximum must be equal.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is equal
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       }
       if (obj instanceof LongRange == false) {
           return false;
       }
       LongRange range = (LongRange) obj;
       return min == range.min && max == range.max;
   }
   /**
*

Gets a hashCode for the range.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       if (hashCode == 0) {
           hashCode = 17;
           hashCode = 37 * hashCode + getClass().hashCode();
           hashCode = 37 * hashCode + ((int) (min ^ (min >> 32)));
           hashCode = 37 * hashCode + ((int) (max ^ (max >> 32)));
       }
       return hashCode;
   }
   /**
*

Gets the range as a String.

    *
*

The format of the String is "Range[min,max]".

    *
    * @return the String representation of this range
    */
   public String toString() {
       if (toString == null) {
           StringBuffer buf = new StringBuffer(32);
           buf.append("Range[");
           buf.append(min);
           buf.append(",");
           buf.append(max);
           buf.append("]");
           toString = buf.toString();
       }
       return toString;
   }
   /**
*

Returns an array containing all the long values in the range.

    *
    * @return the long[] representation of this range
    * @since 2.4
    */
   public long[] toArray() {
       long[] array = new long[(int)(max - min + 1L)];
       for(int i = 0; i < array.length; i++) {
           array[i] = min + i;
       }
       return array;
   }

} /*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

*

Range represents a range of numbers of the same type.

* 
*

Specific subclasses hold the range values as different types. Each * subclass should be immutable and {@link java.io.Serializable Serializable} * if possible.

*
* @author Stephen Colebourne
* @since 2.0
* @version $Id: Range.java 437554 2006-08-28 06:21:41Z bayard $
*/

abstract class Range {

   /**
*

Constructs a new range.

    */
   public Range() {
       super();
   }
   // Accessors
   //--------------------------------------------------------------------
   /**
*

Gets the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public abstract Number getMinimumNumber();
   /**
*

Gets the minimum number in this range as a long.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public long getMinimumLong() {
       return getMinimumNumber().longValue();
   }
   /**
*

Gets the minimum number in this range as a int.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public int getMinimumInteger() {
       return getMinimumNumber().intValue();
   }
   /**
*

Gets the minimum number in this range as a double.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public double getMinimumDouble() {
       return getMinimumNumber().doubleValue();
   }
   /**
*

Gets the minimum number in this range as a float.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public float getMinimumFloat() {
       return getMinimumNumber().floatValue();
   }
   /**
*

Gets the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public abstract Number getMaximumNumber();
   /**
*

Gets the maximum number in this range as a long.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public long getMaximumLong() {
       return getMaximumNumber().longValue();
   }
   /**
*

Gets the maximum number in this range as a int.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public int getMaximumInteger() {
       return getMaximumNumber().intValue();
   }
   /**
*

Gets the maximum number in this range as a double.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public double getMaximumDouble() {
       return getMaximumNumber().doubleValue();
   }
   /**
*

Gets the maximum number in this range as a float.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public float getMaximumFloat() {
       return getMaximumNumber().floatValue();
   }
   // Include tests
   //--------------------------------------------------------------------
   
   /**
*

Tests whether the specified Number occurs within * this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    *
    * @param number  the number to test, may be null
    * @return true if the specified number occurs within this range
    * @throws IllegalArgumentException if the Number cannot be compared
    */
   public abstract boolean containsNumber(Number number);
   /**
*

Tests whether the specified Number occurs within * this range using long comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsLong(long)} method.

    *
    * @param value  the long to test, may be null
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(Number value) {
       if (value == null) {
           return false;
       }
       return containsLong(value.longValue());
   }
   /**
*

Tests whether the specified long occurs within * this range using long comparison.

    * 
*

This implementation uses the {@link #getMinimumLong()} and * {@link #getMaximumLong()} methods and should be good for most uses.

    * 
    * @param value  the long to test
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(long value) {
       return value >= getMinimumLong() && value <= getMaximumLong();
   }
   /**
*

Tests whether the specified Number occurs within * this range using int comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsInteger(int)} method.

    *
    * @param value  the integer to test, may be null
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(Number value) {
       if (value == null) {
           return false;
       }
       return containsInteger(value.intValue());
   }
   /**
*

Tests whether the specified int occurs within * this range using int comparison.

    * 
*

This implementation uses the {@link #getMinimumInteger()} and * {@link #getMaximumInteger()} methods and should be good for most uses.

    * 
    * @param value  the int to test
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(int value) {
       return value >= getMinimumInteger() && value <= getMaximumInteger();
   }
   /**
*

Tests whether the specified Number occurs within * this range using double comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsDouble(double)} method.

    *
    * @param value  the double to test, may be null
    * @return true if the specified number occurs within this
    *  range by double comparison
    */
   public boolean containsDouble(Number value) {
       if (value == null) {
           return false;
       }
       return containsDouble(value.doubleValue());
   }
   /**
*

Tests whether the specified double occurs within * this range using double comparison.

    * 
*

This implementation uses the {@link #getMinimumDouble()} and * {@link #getMaximumDouble()} methods and should be good for most uses.

    * 
    * @param value  the double to test
    * @return true if the specified number occurs within this
    *  range by double comparison
    */
   public boolean containsDouble(double value) {
       int compareMin = compare(getMinimumDouble(), value);
       int compareMax = compare(getMaximumDouble(), value);
       return compareMin <= 0 && compareMax >= 0;
   }
   /**
*

Tests whether the specified Number occurs within * this range using float comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsFloat(float)} method.

    *
    * @param value  the float to test, may be null
    * @return true if the specified number occurs within this
    *  range by float comparison
    */
   public boolean containsFloat(Number value) {
       if (value == null) {
           return false;
       }
       return containsFloat(value.floatValue());
   }
   /**
*

Tests whether the specified float occurs within * this range using float comparison.

    * 
*

This implementation uses the {@link #getMinimumFloat()} and * {@link #getMaximumFloat()} methods and should be good for most uses.

    * 
    * @param value  the float to test
    * @return true if the specified number occurs within this
    *  range by float comparison
    */
   public boolean containsFloat(float value) {
       int compareMin = compare(getMinimumFloat(), value);
       int compareMax = compare(getMaximumFloat(), value);
       return compareMin <= 0 && compareMax >= 0;
   }
   // Range tests
   //--------------------------------------------------------------------
   /**
*

Tests whether the specified range occurs entirely within this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation uses the {@link #containsNumber(Number)} method. * Subclasses may be able to optimise this.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range occurs entirely within
    *  this range; otherwise, false
    * @throws IllegalArgumentException if the Range cannot be compared
    */
   public boolean containsRange(Range range) {
       if (range == null) {
           return false;
       }
       return containsNumber(range.getMinimumNumber()) 
           && containsNumber(range.getMaximumNumber());
   }
   /**
*

Tests whether the specified range overlaps with this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation uses the {@link #containsNumber(Number)} and * {@link #containsRange(Range)} methods. * Subclasses may be able to optimise this.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range overlaps with this
    *  range; otherwise, false
    * @throws IllegalArgumentException if the Range cannot be compared
    */
   public boolean overlapsRange(Range range) {
       if (range == null) {
           return false;
       }
       return range.containsNumber(getMinimumNumber())
           || range.containsNumber(getMaximumNumber())
           || containsNumber(range.getMinimumNumber());
   }
   // Basics
   //--------------------------------------------------------------------
   /**
*

Compares this range to another object to test if they are equal.

.
    * 
*

To be equal, the class, minimum and maximum must be equal.

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is equal
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       } else if (obj == null || obj.getClass() != getClass()) {
           return false;
       } else {
           Range range = (Range) obj;
           return getMinimumNumber().equals(range.getMinimumNumber()) &&
                  getMaximumNumber().equals(range.getMaximumNumber());
       }
   }
   /**
*

Gets a hashCode for the range.

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       int result = 17;
       result = 37 * result + getClass().hashCode();
       result = 37 * result + getMinimumNumber().hashCode();
       result = 37 * result + getMaximumNumber().hashCode();
       return result;
   }
   /**
*

Gets the range as a String.

    *
*

The format of the String is "Range[min,max]".

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @return the String representation of this range
    */
   public String toString() {
       StringBuffer buf = new StringBuffer(32);
       buf.append("Range[");
       buf.append(getMinimumNumber());
       buf.append(",");
       buf.append(getMaximumNumber());
       buf.append("]");
       return buf.toString();
   }
   /**
*

Compares two doubles for order.

    *
*

This method is more comprehensive than the standard Java greater * than, less than and equals operators.

*
    *
  • It returns -1 if the first value is less than the second.
  • *
  • It returns +1 if the first value is greater than the second.
  • *
  • It returns 0 if the values are equal.
  • *
    *
*

* The ordering is as follows, largest to smallest: *

    *
  • NaN *
  • Positive infinity *
  • Maximum double *
  • Normal positive numbers *
  • +0.0 *
  • -0.0 *
  • Normal negative numbers *
  • Minimum double (-Double.MAX_VALUE) *
  • Negative infinity *
*

    *
*

Comparing NaN with NaN will * return 0.

    * 
    * @param lhs  the first double
    * @param rhs  the second double
    * @return -1 if lhs is less, +1 if greater,
    *  0 if equal to rhs
    */
   public static int compare(double lhs, double rhs) {
       if (lhs < rhs) {
           return -1;
       }
       if (lhs > rhs) {
           return +1;
       }
       // Need to compare bits to handle 0.0 == -0.0 being true
       // compare should put -0.0 < +0.0
       // Two NaNs are also == for compare purposes
       // where NaN == NaN is false
       long lhsBits = Double.doubleToLongBits(lhs);
       long rhsBits = Double.doubleToLongBits(rhs);
       if (lhsBits == rhsBits) {
           return 0;
       }
       // Something exotic! A comparison to NaN or 0.0 vs -0.0
       // Fortunately NaN"s long is > than everything else
       // Also negzeros bits < poszero
       // NAN: 9221120237041090560
       // MAX: 9218868437227405311
       // NEGZERO: -9223372036854775808
       if (lhsBits < rhsBits) {
           return -1;
       } else {
           return +1;
       }
   }
   
   /**
*

Compares two floats for order.

    *
*

This method is more comprehensive than the standard Java greater than, * less than and equals operators.

*
    *
  • It returns -1 if the first value is less than the second. *
  • It returns +1 if the first value is greater than the second. *
  • It returns 0 if the values are equal. *
    *
*

The ordering is as follows, largest to smallest: *

    *
  • NaN *
  • Positive infinity *
  • Maximum float *
  • Normal positive numbers *
  • +0.0 *
  • -0.0 *
  • Normal negative numbers *
  • Minimum float (-Float.MAX_VALUE) *
  • Negative infinity *
    *
    * <p>Comparing NaN with NaN will return
* 0.

    * 
    * @param lhs  the first float
    * @param rhs  the second float
    * @return -1 if lhs is less, +1 if greater,
    *  0 if equal to rhs
    */
   public static int compare(float lhs, float rhs) {
       if (lhs < rhs) {
           return -1;
       }
       if (lhs > rhs) {
           return +1;
       }
       //Need to compare bits to handle 0.0 == -0.0 being true
       // compare should put -0.0 < +0.0
       // Two NaNs are also == for compare purposes
       // where NaN == NaN is false
       int lhsBits = Float.floatToIntBits(lhs);
       int rhsBits = Float.floatToIntBits(rhs);
       if (lhsBits == rhsBits) {
           return 0;
       }
       //Something exotic! A comparison to NaN or 0.0 vs -0.0
       //Fortunately NaN"s int is > than everything else
       //Also negzeros bits < poszero
       //NAN: 2143289344
       //MAX: 2139095039
       //NEGZERO: -2147483648
       if (lhsBits < rhsBits) {
           return -1;
       } else {
           return +1;
       }
   }

}


 </source>
   
  
 
  



NumberRange represents an inclusive range of java.lang.Number objects of the same type.

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.Serializable; /**

*

NumberRange represents an inclusive range of * {@link java.lang.Number} objects of the same type.

*
* @author 
* @author Stephen Colebourne
* @since 2.0 (previously in org.apache.rumons.lang)
* @version $Id: NumberRange.java 437554 2006-08-28 06:21:41Z bayard $
*/

public final class NumberRange extends Range implements Serializable {

   /**
    * Required for serialization support.
    * 
    * @see java.io.Serializable
    */
   private static final long serialVersionUID = 71849363892710L;
   /**
    * The minimum number in this range.
    */
   private final Number min;
   /**
    * The maximum number in this range.
    */
   private final Number max;
   
   /**
    * Cached output hashCode (class is immutable).
    */
   private transient int hashCode = 0;
   /**
    * Cached output toString (class is immutable).
    */
   private transient String toString = null;
   /**
*

Constructs a new NumberRange using the specified * number as both the minimum and maximum in this range.

    *
    * @param num the number to use for this range
    * @throws IllegalArgumentException if the number is null
    * @throws IllegalArgumentException if the number doesn"t implement Comparable
    * @throws IllegalArgumentException if the number is Double.NaN or Float.NaN
    */
   public NumberRange(Number num) {
       if (num == null) {
           throw new IllegalArgumentException("The number must not be null");
       }
       if (num instanceof Comparable == false) {
           throw new IllegalArgumentException("The number must implement Comparable");
       }
       if (num instanceof Double && ((Double) num).isNaN()) {
           throw new IllegalArgumentException("The number must not be NaN");
       }
       if (num instanceof Float && ((Float) num).isNaN()) {
           throw new IllegalArgumentException("The number must not be NaN");
       }
       this.min = num;
       this.max = num;
   }
   /**
*

Constructs a new NumberRange with the specified * minimum and maximum numbers (both inclusive).

    * 
*

The arguments may be passed in the order (min,max) or (max,min). The * {@link #getMinimumNumber()} and {@link #getMaximumNumber()} methods will return the * correct value.

    * 
*

This constructor is designed to be used with two Number * objects of the same type. If two objects of different types are passed in, * an exception is thrown.

    *
    * @param num1  first number that defines the edge of the range, inclusive
    * @param num2  second number that defines the edge of the range, inclusive
    * @throws IllegalArgumentException if either number is null
    * @throws IllegalArgumentException if the numbers are of different types
    * @throws IllegalArgumentException if the numbers don"t implement Comparable
    */
   public NumberRange(Number num1, Number num2) {
       if (num1 == null || num2 == null) {
           throw new IllegalArgumentException("The numbers must not be null");
       }
       if (num1.getClass() != num2.getClass()) {
           throw new IllegalArgumentException("The numbers must be of the same type");
       }
       if (num1 instanceof Comparable == false) {
           throw new IllegalArgumentException("The numbers must implement Comparable");
       }
       if (num1 instanceof Double) {
           if (((Double) num1).isNaN() || ((Double) num2).isNaN()) {
               throw new IllegalArgumentException("The number must not be NaN");
           }
       } else if (num1 instanceof Float) {
           if (((Float) num1).isNaN() || ((Float) num2).isNaN()) {
               throw new IllegalArgumentException("The number must not be NaN");
           }
       }
       
       int compare = ((Comparable) num1).rupareTo(num2);
       if (compare == 0) {
           this.min = num1;
           this.max = num1;
       } else if (compare > 0) {
           this.min = num2;
           this.max = num1;
       } else {
           this.min = num1;
           this.max = num2;
       }
   }
   
   // Accessors
   //--------------------------------------------------------------------
   /**
*

Returns the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public Number getMinimumNumber() {
       return min;
   }
   /**
*

Returns the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public Number getMaximumNumber() {
       return max;
   }
   // Tests
   //--------------------------------------------------------------------
   
   /**
*

Tests whether the specified number occurs within * this range.

    * 
*

null is handled and returns false.

    *
    * @param number  the number to test, may be null
    * @return true if the specified number occurs within this range
    * @throws IllegalArgumentException if the number is of a different type to the range
    */
   public boolean containsNumber(Number number) {
       if (number == null) {
           return false;
       }
       if (number.getClass() != min.getClass()) {
           throw new IllegalArgumentException("The number must be of the same type as the range numbers");
       }
       int compareMin = ((Comparable) min).rupareTo(number);
       int compareMax = ((Comparable) max).rupareTo(number);
       return compareMin <= 0 && compareMax >= 0;
   }
   // Range tests
   //--------------------------------------------------------------------
   // use Range implementations
   // Basics
   //--------------------------------------------------------------------
   /**
*

Compares this range to another object to test if they are equal.

.
    * 
*

To be equal, the class, minimum and maximum must be equal.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is equal
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       }
       if (obj instanceof NumberRange == false) {
           return false;
       }
       NumberRange range = (NumberRange) obj;
       return min.equals(range.min) && max.equals(range.max);
   }
   /**
*

Gets a hashCode for the range.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       if (hashCode == 0) {
           hashCode = 17;
           hashCode = 37 * hashCode + getClass().hashCode();
           hashCode = 37 * hashCode + min.hashCode();
           hashCode = 37 * hashCode + max.hashCode();
       }
       return hashCode;
   }
   /**
*

Gets the range as a String.

    *
*

The format of the String is "Range[min,max]".

    *
    * @return the String representation of this range
    */
   public String toString() {
       if (toString == null) {
           StringBuffer buf = new StringBuffer(32);
           buf.append("Range[");
           buf.append(min);
           buf.append(",");
           buf.append(max);
           buf.append("]");
           toString = buf.toString();
       }
       return toString;
   }

} /*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

*

Range represents a range of numbers of the same type.

* 
*

Specific subclasses hold the range values as different types. Each * subclass should be immutable and {@link java.io.Serializable Serializable} * if possible.

*
* @author Stephen Colebourne
* @since 2.0
* @version $Id: Range.java 437554 2006-08-28 06:21:41Z bayard $
*/

abstract class Range {

   /**
*

Constructs a new range.

    */
   public Range() {
       super();
   }
   // Accessors
   //--------------------------------------------------------------------
   /**
*

Gets the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public abstract Number getMinimumNumber();
   /**
*

Gets the minimum number in this range as a long.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public long getMinimumLong() {
       return getMinimumNumber().longValue();
   }
   /**
*

Gets the minimum number in this range as a int.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public int getMinimumInteger() {
       return getMinimumNumber().intValue();
   }
   /**
*

Gets the minimum number in this range as a double.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public double getMinimumDouble() {
       return getMinimumNumber().doubleValue();
   }
   /**
*

Gets the minimum number in this range as a float.

    * 
*

This implementation uses the {@link #getMinimumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the minimum number in this range
    */
   public float getMinimumFloat() {
       return getMinimumNumber().floatValue();
   }
   /**
*

Gets the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public abstract Number getMaximumNumber();
   /**
*

Gets the maximum number in this range as a long.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public long getMaximumLong() {
       return getMaximumNumber().longValue();
   }
   /**
*

Gets the maximum number in this range as a int.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public int getMaximumInteger() {
       return getMaximumNumber().intValue();
   }
   /**
*

Gets the maximum number in this range as a double.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public double getMaximumDouble() {
       return getMaximumNumber().doubleValue();
   }
   /**
*

Gets the maximum number in this range as a float.

    * 
*

This implementation uses the {@link #getMaximumNumber()} method. * Subclasses may be able to optimise this.

    *
    * @return the maximum number in this range
    */
   public float getMaximumFloat() {
       return getMaximumNumber().floatValue();
   }
   // Include tests
   //--------------------------------------------------------------------
   
   /**
*

Tests whether the specified Number occurs within * this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    *
    * @param number  the number to test, may be null
    * @return true if the specified number occurs within this range
    * @throws IllegalArgumentException if the Number cannot be compared
    */
   public abstract boolean containsNumber(Number number);
   /**
*

Tests whether the specified Number occurs within * this range using long comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsLong(long)} method.

    *
    * @param value  the long to test, may be null
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(Number value) {
       if (value == null) {
           return false;
       }
       return containsLong(value.longValue());
   }
   /**
*

Tests whether the specified long occurs within * this range using long comparison.

    * 
*

This implementation uses the {@link #getMinimumLong()} and * {@link #getMaximumLong()} methods and should be good for most uses.

    * 
    * @param value  the long to test
    * @return true if the specified number occurs within this
    *  range by long comparison
    */
   public boolean containsLong(long value) {
       return value >= getMinimumLong() && value <= getMaximumLong();
   }
   /**
*

Tests whether the specified Number occurs within * this range using int comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsInteger(int)} method.

    *
    * @param value  the integer to test, may be null
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(Number value) {
       if (value == null) {
           return false;
       }
       return containsInteger(value.intValue());
   }
   /**
*

Tests whether the specified int occurs within * this range using int comparison.

    * 
*

This implementation uses the {@link #getMinimumInteger()} and * {@link #getMaximumInteger()} methods and should be good for most uses.

    * 
    * @param value  the int to test
    * @return true if the specified number occurs within this
    *  range by int comparison
    */
   public boolean containsInteger(int value) {
       return value >= getMinimumInteger() && value <= getMaximumInteger();
   }
   /**
*

Tests whether the specified Number occurs within * this range using double comparison..

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsDouble(double)} method.

    *
    * @param value  the double to test, may be null
    * @return true if the specified number occurs within this
    *  range by double comparison
    */
   public boolean containsDouble(Number value) {
       if (value == null) {
           return false;
       }
       return containsDouble(value.doubleValue());
   }
   /**
*

Tests whether the specified double occurs within * this range using double comparison.

    * 
*

This implementation uses the {@link #getMinimumDouble()} and * {@link #getMaximumDouble()} methods and should be good for most uses.

    * 
    * @param value  the double to test
    * @return true if the specified number occurs within this
    *  range by double comparison
    */
   public boolean containsDouble(double value) {
       int compareMin = compare(getMinimumDouble(), value);
       int compareMax = compare(getMaximumDouble(), value);
       return compareMin <= 0 && compareMax >= 0;
   }
   /**
*

Tests whether the specified Number occurs within * this range using float comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation forwards to the {@link #containsFloat(float)} method.

    *
    * @param value  the float to test, may be null
    * @return true if the specified number occurs within this
    *  range by float comparison
    */
   public boolean containsFloat(Number value) {
       if (value == null) {
           return false;
       }
       return containsFloat(value.floatValue());
   }
   /**
*

Tests whether the specified float occurs within * this range using float comparison.

    * 
*

This implementation uses the {@link #getMinimumFloat()} and * {@link #getMaximumFloat()} methods and should be good for most uses.

    * 
    * @param value  the float to test
    * @return true if the specified number occurs within this
    *  range by float comparison
    */
   public boolean containsFloat(float value) {
       int compareMin = compare(getMinimumFloat(), value);
       int compareMax = compare(getMaximumFloat(), value);
       return compareMin <= 0 && compareMax >= 0;
   }
   // Range tests
   //--------------------------------------------------------------------
   /**
*

Tests whether the specified range occurs entirely within this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation uses the {@link #containsNumber(Number)} method. * Subclasses may be able to optimise this.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range occurs entirely within
    *  this range; otherwise, false
    * @throws IllegalArgumentException if the Range cannot be compared
    */
   public boolean containsRange(Range range) {
       if (range == null) {
           return false;
       }
       return containsNumber(range.getMinimumNumber()) 
           && containsNumber(range.getMaximumNumber());
   }
   /**
*

Tests whether the specified range overlaps with this range.

    * 
*

The exact comparison implementation varies by subclass. It is * intended that an int specific subclass will compare using * int comparison.

    * 
*

null is handled and returns false.

    * 
*

This implementation uses the {@link #containsNumber(Number)} and * {@link #containsRange(Range)} methods. * Subclasses may be able to optimise this.

    *
    * @param range  the range to test, may be null
    * @return true if the specified range overlaps with this
    *  range; otherwise, false
    * @throws IllegalArgumentException if the Range cannot be compared
    */
   public boolean overlapsRange(Range range) {
       if (range == null) {
           return false;
       }
       return range.containsNumber(getMinimumNumber())
           || range.containsNumber(getMaximumNumber())
           || containsNumber(range.getMinimumNumber());
   }
   // Basics
   //--------------------------------------------------------------------
   /**
*

Compares this range to another object to test if they are equal.

.
    * 
*

To be equal, the class, minimum and maximum must be equal.

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is equal
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       } else if (obj == null || obj.getClass() != getClass()) {
           return false;
       } else {
           Range range = (Range) obj;
           return getMinimumNumber().equals(range.getMinimumNumber()) &&
                  getMaximumNumber().equals(range.getMaximumNumber());
       }
   }
   /**
*

Gets a hashCode for the range.

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       int result = 17;
       result = 37 * result + getClass().hashCode();
       result = 37 * result + getMinimumNumber().hashCode();
       result = 37 * result + getMaximumNumber().hashCode();
       return result;
   }
   /**
*

Gets the range as a String.

    *
*

The format of the String is "Range[min,max]".

    * 
*

This implementation uses the {@link #getMinimumNumber()} and * {@link #getMaximumNumber()} methods. * Subclasses may be able to optimise this.

    *
    * @return the String representation of this range
    */
   public String toString() {
       StringBuffer buf = new StringBuffer(32);
       buf.append("Range[");
       buf.append(getMinimumNumber());
       buf.append(",");
       buf.append(getMaximumNumber());
       buf.append("]");
       return buf.toString();
   }
   /**
*

Compares two doubles for order.

    *
*

This method is more comprehensive than the standard Java greater * than, less than and equals operators.

*
    *
  • It returns -1 if the first value is less than the second.
  • *
  • It returns +1 if the first value is greater than the second.
  • *
  • It returns 0 if the values are equal.
  • *
    *
*

* The ordering is as follows, largest to smallest: *

    *
  • NaN *
  • Positive infinity *
  • Maximum double *
  • Normal positive numbers *
  • +0.0 *
  • -0.0 *
  • Normal negative numbers *
  • Minimum double (-Double.MAX_VALUE) *
  • Negative infinity *
*

    *
*

Comparing NaN with NaN will * return 0.

    * 
    * @param lhs  the first double
    * @param rhs  the second double
    * @return -1 if lhs is less, +1 if greater,
    *  0 if equal to rhs
    */
   public static int compare(double lhs, double rhs) {
       if (lhs < rhs) {
           return -1;
       }
       if (lhs > rhs) {
           return +1;
       }
       // Need to compare bits to handle 0.0 == -0.0 being true
       // compare should put -0.0 < +0.0
       // Two NaNs are also == for compare purposes
       // where NaN == NaN is false
       long lhsBits = Double.doubleToLongBits(lhs);
       long rhsBits = Double.doubleToLongBits(rhs);
       if (lhsBits == rhsBits) {
           return 0;
       }
       // Something exotic! A comparison to NaN or 0.0 vs -0.0
       // Fortunately NaN"s long is > than everything else
       // Also negzeros bits < poszero
       // NAN: 9221120237041090560
       // MAX: 9218868437227405311
       // NEGZERO: -9223372036854775808
       if (lhsBits < rhsBits) {
           return -1;
       } else {
           return +1;
       }
   }
   
   /**
*

Compares two floats for order.

    *
*

This method is more comprehensive than the standard Java greater than, * less than and equals operators.

*
    *
  • It returns -1 if the first value is less than the second. *
  • It returns +1 if the first value is greater than the second. *
  • It returns 0 if the values are equal. *
    *
*

The ordering is as follows, largest to smallest: *

    *
  • NaN *
  • Positive infinity *
  • Maximum float *
  • Normal positive numbers *
  • +0.0 *
  • -0.0 *
  • Normal negative numbers *
  • Minimum float (-Float.MAX_VALUE) *
  • Negative infinity *
    *
    * <p>Comparing NaN with NaN will return
* 0.

    * 
    * @param lhs  the first float
    * @param rhs  the second float
    * @return -1 if lhs is less, +1 if greater,
    *  0 if equal to rhs
    */
   public static int compare(float lhs, float rhs) {
       if (lhs < rhs) {
           return -1;
       }
       if (lhs > rhs) {
           return +1;
       }
       //Need to compare bits to handle 0.0 == -0.0 being true
       // compare should put -0.0 < +0.0
       // Two NaNs are also == for compare purposes
       // where NaN == NaN is false
       int lhsBits = Float.floatToIntBits(lhs);
       int rhsBits = Float.floatToIntBits(rhs);
       if (lhsBits == rhsBits) {
           return 0;
       }
       //Something exotic! A comparison to NaN or 0.0 vs -0.0
       //Fortunately NaN"s int is > than everything else
       //Also negzeros bits < poszero
       //NAN: 2143289344
       //MAX: 2139095039
       //NEGZERO: -2147483648
       if (lhsBits < rhsBits) {
           return -1;
       } else {
           return +1;
       }
   }

}


 </source>
   
  
 
  



Represents a range of Number objects.

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

*

Represents a range of {@link Number} objects.

* 
*

This class uses double comparisons. This means that it * is unsuitable for dealing with large Long, BigDecimal * or BigInteger numbers.

*
* @author 
* @author Stephen Colebourne
* @since 1.0
* @version $Revision: 437554 $ $Date: 2006-08-27 23:21:41 -0700 (Sun, 27 Aug 2006) $
* 
* 
*/

public final class NumberRange {

   /* The minimum number in this range. */
   private final Number min;
   /* The maximum number in this range. */
   private final Number max;
   /**
*

Constructs a new NumberRange using * number as both the minimum and maximum in * this range.

    *
    * @param num the number to use for this range
    * @throws NullPointerException if the number is null
    */
   public NumberRange(Number num) {
       if (num == null) {
           throw new NullPointerException("The number must not be null");
       }
       this.min = num;
       this.max = num;
   }
   /**
*

Constructs a new NumberRange with the specified * minimum and maximum numbers.

    * 
*

If the maximum is less than the minimum, the range will be constructed * from the minimum value to the minimum value, not what you would expect!.

    *
    * @param min the minimum number in this range
    * @param max the maximum number in this range
    * @throws NullPointerException if either the minimum or maximum number is
    *  null
    */
   public NumberRange(Number min, Number max) {
       if (min == null) {
           throw new NullPointerException("The minimum value must not be null");
       } else if (max == null) {
           throw new NullPointerException("The maximum value must not be null");
       }
       if (max.doubleValue() < min.doubleValue()) {
           this.min = this.max = min;
       } else {
           this.min = min;
           this.max = max;
       }
   }
   /**
*

Returns the minimum number in this range.

    *
    * @return the minimum number in this range
    */
   public Number getMinimum() {
       return min;
   }
   /**
*

Returns the maximum number in this range.

    *
    * @return the maximum number in this range
    */
   public Number getMaximum() {
       return max;
   }
   /**
*

Tests whether the specified number occurs within * this range using double comparison.

    *
    * @param number the number to test
    * @return true if the specified number occurs within this
    *  range; otherwise, false
    */
   public boolean includesNumber(Number number) {
       if (number == null) {
           return false;
       } else {
           return !(min.doubleValue() > number.doubleValue()) &&
               !(max.doubleValue() < number.doubleValue());
       }
   }
   /**
*

Tests whether the specified range occurs entirely within this * range using double comparison.

    *
    * @param range the range to test
    * @return true if the specified range occurs entirely within
    *  this range; otherwise, false
    */
   public boolean includesRange(NumberRange range) {
       if (range == null) {
           return false;
       } else {
           return includesNumber(range.min) && includesNumber(range.max);
       }
   }
   /**
*

Tests whether the specified range overlaps with this range * using double comparison.

    *
    * @param range the range to test
    * @return true if the specified range overlaps with this
    *  range; otherwise, false
    */
   public boolean overlaps(NumberRange range) {
       if (range == null) {
           return false;
       } else {
           return range.includesNumber(min) || range.includesNumber(max) || 
               includesRange(range);
       }
   }
   /**
*

Indicates whether some other Object is * "equal" to this one.

    *
    * @param obj the reference object with which to compare
    * @return true if this object is the same as the obj
    *  argument; false otherwise
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       } else if (!(obj instanceof NumberRange)) {
           return false;
       } else {
           NumberRange range = (NumberRange)obj;
           return min.equals(range.min) && max.equals(range.max);
       }
   }
   /**
*

Returns a hash code value for this object.

    *
    * @return a hash code value for this object
    */
   public int hashCode() {
       int result = 17;
       result = 37 * result + min.hashCode();
       result = 37 * result + max.hashCode();
       return result;
   }
   /**
*

Returns the string representation of this range.

    *
*

This string is the string representation of the minimum and * maximum numbers in the range, separated by a hyphen. If a number * is negative, then it is enclosed in parentheses.

    *
    * @return the string representation of this range
    */
   public String toString() {
       StringBuffer sb = new StringBuffer();
       if (min.doubleValue() < 0) {
           sb.append("(")
               .append(min)
               .append(")");
       } else {
           sb.append(min);
       }
       sb.append("-");
       if (max.doubleValue() < 0) {
           sb.append("(")
               .append(max)
               .append(")");
       } else {
           sb.append(max);
       }
       return sb.toString();
   }

}


 </source>
   
  
 
  



Represents a sequence of integer values, either ascending or descending.

   <source lang="java">
   

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

import java.util.Iterator; /**

* Represents a sequence of integer values, either ascending or descending. The sequence is always inclusive (of the
* finish value).
*/

public final class IntegerRange implements Iterable<Integer> {

   private final int start;
   private final int finish;
   private class RangeIterator implements Iterator<Integer>
   {
       private final int increment;
       private int value = start;
       private boolean hasNext = true;
       RangeIterator()
       {
           increment = start < finish ? +1 : -1;
       }
       public boolean hasNext()
       {
           return hasNext;
       }
       public Integer next()
       {
           if (!hasNext) throw new IllegalStateException();
           int result = value;
           hasNext = value != finish;
           value += increment;
           return result;
       }
       public void remove()
       {
           throw new UnsupportedOperationException();
       }
   }
   public IntegerRange(final int start, final int finish)
   {
       this.start = start;
       this.finish = finish;
   }
   public int getFinish()
   {
       return finish;
   }
   public int getStart()
   {
       return start;
   }
   @Override
   public String toString()
   {
       return String.format("%d..%d", start, finish);
   }
   /**
    * The main puprose of a range object is to produce an Iterator. Since IntegerRange is iterable, it is useful with
    * the Tapestry Loop component, but also with the Java for loop!
    */
   public Iterator<Integer> iterator()
   {
       return new RangeIterator();
   }
   @Override
   public int hashCode()
   {
       final int PRIME = 31;
       int result = PRIME + finish;
       result = PRIME * result + start;
       return result;
   }
   /**
    * Returns true if the other object is an IntegerRange with the same start and finish values.
    */
   @Override
   public boolean equals(Object obj)
   {
       if (this == obj) return true;
       if (obj == null) return false;
       if (getClass() != obj.getClass()) return false;
       final IntegerRange other = (IntegerRange) obj;
       if (finish != other.finish) return false;
       return start == other.start;
   }

}



 </source>
   
  
 
  



This constructs an Iterator over each day in a date range defined by a focus date and range style.

   <source lang="java">
   

import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.TimeZone;

/**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 /**
  * The UTC time zone  (often referred to as GMT).
  */
 public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("GMT");
 /**
  * Number of milliseconds in a standard second.
  * @since 2.1
  */
 public static final long MILLIS_PER_SECOND = 1000;
 /**
  * Number of milliseconds in a standard minute.
  * @since 2.1
  */
 public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
 /**
  * Number of milliseconds in a standard hour.
  * @since 2.1
  */
 public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
 /**
  * Number of milliseconds in a standard day.
  * @since 2.1
  */
 public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;
 /**
  * This is half a month, so this represents whether a date is in the top
  * or bottom half of the month.
  */
 public final static int SEMI_MONTH = 1001;
 private static final int[][] fields = {
         {Calendar.MILLISECOND},
         {Calendar.SECOND},
         {Calendar.MINUTE},
         {Calendar.HOUR_OF_DAY, Calendar.HOUR},
         {Calendar.DATE, Calendar.DAY_OF_MONTH, Calendar.AM_PM 
             /* Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK, Calendar.DAY_OF_WEEK_IN_MONTH */
         },
         {Calendar.MONTH, DateUtils.SEMI_MONTH},
         {Calendar.YEAR},
         {Calendar.ERA}};
 /**
  * A week range, starting on Sunday.
  */
 public final static int RANGE_WEEK_SUNDAY = 1;
 /**
  * A week range, starting on Monday.
  */
 public final static int RANGE_WEEK_MONDAY = 2;
 /**
  * A week range, starting on the day focused.
  */
 public final static int RANGE_WEEK_RELATIVE = 3;
 /**
  * A week range, centered around the day focused.
  */
 public final static int RANGE_WEEK_CENTER = 4;
 /**
  * A month range, the week starting on Sunday.
  */
 public final static int RANGE_MONTH_SUNDAY = 5;
 /**
  * A month range, the week starting on Monday.
  */
 public final static int RANGE_MONTH_MONDAY = 6;
 //-----------------------------------------------------------------------
 /**
*

This constructs an Iterator over each day in a date * range defined by a focus date and range style.

  *
*

For instance, passing Thursday, July 4, 2002 and a * RANGE_MONTH_SUNDAY will return an Iterator * that starts with Sunday, June 30, 2002 and ends with Saturday, August 3, * 2002, returning a Calendar instance for each intermediate day.

  *
*

This method provides an iterator that returns Calendar objects. * The days are progressed using {@link Calendar#add(int, int)}.

  *
  * @param focus  the date to work with, not null
  * @param rangeStyle  the style constant to use. Must be one of
  * {@link DateUtils#RANGE_MONTH_SUNDAY}, 
  * {@link DateUtils#RANGE_MONTH_MONDAY},
  * {@link DateUtils#RANGE_WEEK_SUNDAY},
  * {@link DateUtils#RANGE_WEEK_MONDAY},
  * {@link DateUtils#RANGE_WEEK_RELATIVE},
  * {@link DateUtils#RANGE_WEEK_CENTER}
  * @return the date iterator, which always returns Calendar instances
  * @throws IllegalArgumentException if the date is null
  * @throws IllegalArgumentException if the rangeStyle is invalid
  */
 public static Iterator iterator(Date focus, int rangeStyle) {
     if (focus == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     Calendar gval = Calendar.getInstance();
     gval.setTime(focus);
     return iterator(gval, rangeStyle);
 }
 /**
*

This constructs an Iterator over each day in a date * range defined by a focus date and range style.

  *
*

For instance, passing Thursday, July 4, 2002 and a * RANGE_MONTH_SUNDAY will return an Iterator * that starts with Sunday, June 30, 2002 and ends with Saturday, August 3, * 2002, returning a Calendar instance for each intermediate day.

  *
*

This method provides an iterator that returns Calendar objects. * The days are progressed using {@link Calendar#add(int, int)}.

  *
  * @param focus  the date to work with
  * @param rangeStyle  the style constant to use. Must be one of
  * {@link DateUtils#RANGE_MONTH_SUNDAY}, 
  * {@link DateUtils#RANGE_MONTH_MONDAY},
  * {@link DateUtils#RANGE_WEEK_SUNDAY},
  * {@link DateUtils#RANGE_WEEK_MONDAY},
  * {@link DateUtils#RANGE_WEEK_RELATIVE},
  * {@link DateUtils#RANGE_WEEK_CENTER}
  * @return the date iterator
  * @throws IllegalArgumentException if the date is null
  * @throws IllegalArgumentException if the rangeStyle is invalid
  */
 public static Iterator iterator(Calendar focus, int rangeStyle) {
     if (focus == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     Calendar start = null;
     Calendar end = null;
     int startCutoff = Calendar.SUNDAY;
     int endCutoff = Calendar.SATURDAY;
     switch (rangeStyle) {
         case RANGE_MONTH_SUNDAY:
         case RANGE_MONTH_MONDAY:
             //Set start to the first of the month
             start = truncate(focus, Calendar.MONTH);
             //Set end to the last of the month
             end = (Calendar) start.clone();
             end.add(Calendar.MONTH, 1);
             end.add(Calendar.DATE, -1);
             //Loop start back to the previous sunday or monday
             if (rangeStyle == RANGE_MONTH_MONDAY) {
                 startCutoff = Calendar.MONDAY;
                 endCutoff = Calendar.SUNDAY;
             }
             break;
         case RANGE_WEEK_SUNDAY:
         case RANGE_WEEK_MONDAY:
         case RANGE_WEEK_RELATIVE:
         case RANGE_WEEK_CENTER:
             //Set start and end to the current date
             start = truncate(focus, Calendar.DATE);
             end = truncate(focus, Calendar.DATE);
             switch (rangeStyle) {
                 case RANGE_WEEK_SUNDAY:
                     //already set by default
                     break;
                 case RANGE_WEEK_MONDAY:
                     startCutoff = Calendar.MONDAY;
                     endCutoff = Calendar.SUNDAY;
                     break;
                 case RANGE_WEEK_RELATIVE:
                     startCutoff = focus.get(Calendar.DAY_OF_WEEK);
                     endCutoff = startCutoff - 1;
                     break;
                 case RANGE_WEEK_CENTER:
                     startCutoff = focus.get(Calendar.DAY_OF_WEEK) - 3;
                     endCutoff = focus.get(Calendar.DAY_OF_WEEK) + 3;
                     break;
             }
             break;
         default:
             throw new IllegalArgumentException("The range style " + rangeStyle + " is not valid.");
     }
     if (startCutoff < Calendar.SUNDAY) {
         startCutoff += 7;
     }
     if (startCutoff > Calendar.SATURDAY) {
         startCutoff -= 7;
     }
     if (endCutoff < Calendar.SUNDAY) {
         endCutoff += 7;
     }
     if (endCutoff > Calendar.SATURDAY) {
         endCutoff -= 7;
     }
     while (start.get(Calendar.DAY_OF_WEEK) != startCutoff) {
         start.add(Calendar.DATE, -1);
     }
     while (end.get(Calendar.DAY_OF_WEEK) != endCutoff) {
         end.add(Calendar.DATE, 1);
     }
     return new DateIterator(start, end);
 }
 /**
*

This constructs an Iterator over each day in a date * range defined by a focus date and range style.

  *
*

For instance, passing Thursday, July 4, 2002 and a * RANGE_MONTH_SUNDAY will return an Iterator * that starts with Sunday, June 30, 2002 and ends with Saturday, August 3, * 2002, returning a Calendar instance for each intermediate day.

  *
  * @param focus  the date to work with, either
  *  Date or Calendar
  * @param rangeStyle  the style constant to use. Must be one of the range
  * styles listed for the {@link #iterator(Calendar, int)} method.
  * @return the date iterator
  * @throws IllegalArgumentException if the date
  *  is null
  * @throws ClassCastException if the object type is
  *  not a Date or Calendar
  */
 public static Iterator iterator(Object focus, int rangeStyle) {
     if (focus == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     if (focus instanceof Date) {
         return iterator((Date) focus, rangeStyle);
     } else if (focus instanceof Calendar) {
         return iterator((Calendar) focus, rangeStyle);
     } else {
         throw new ClassCastException("Could not iterate based on " + focus);
     }
 }
 /**
*

Truncate this date, leaving the field specified as the most * significant field.

  *
*

For example, if you had the datetime of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 13:00:00.000. If this was passed with MONTH, it would * return 1 Mar 2002 0:00:00.000.

  * 
  * @param date  the date to work with, either Date
  *  or Calendar
  * @param field  the field from Calendar
  *  or SEMI_MONTH
  * @return the rounded date
  * @throws IllegalArgumentException if the date
  *  is null
  * @throws ClassCastException if the object type is not a
  *  Date or Calendar
  * @throws ArithmeticException if the year is over 280 million
  */
 public static Date truncate(Object date, int field) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     if (date instanceof Date) {
         return truncate((Date) date, field);
     } else if (date instanceof Calendar) {
         return truncate((Calendar) date, field).getTime();
     } else {
         throw new ClassCastException("Could not truncate " + date);
     }
 }
 /**
*

Truncate this date, leaving the field specified as the most * significant field.

  *
*

For example, if you had the datetime of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 13:00:00.000. If this was passed with MONTH, it would * return 1 Mar 2002 0:00:00.000.

  * 
  * @param date  the date to work with
  * @param field  the field from Calendar
  *  or SEMI_MONTH
  * @return the rounded date (a different object)
  * @throws IllegalArgumentException if the date is null
  * @throws ArithmeticException if the year is over 280 million
  */
 public static Calendar truncate(Calendar date, int field) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     Calendar truncated = (Calendar) date.clone();
     modify(truncated, field, false);
     return truncated;
 }
 //-----------------------------------------------------------------------
 /**
*

Internal calculation method.

  * 
  * @param val  the calendar
  * @param field  the field constant
  * @param round  true to round, false to truncate
  * @throws ArithmeticException if the year is over 280 million
  */
 private static void modify(Calendar val, int field, boolean round) {
     if (val.get(Calendar.YEAR) > 280000000) {
         throw new ArithmeticException("Calendar value too large for accurate calculations");
     }
     
     if (field == Calendar.MILLISECOND) {
         return;
     }
     // ----------------- Fix for LANG-59 ---------------------- START ---------------
     // see http://issues.apache.org/jira/browse/LANG-59
     //
     // Manually truncate milliseconds, seconds and minutes, rather than using
     // Calendar methods.
     Date date = val.getTime();
     long time = date.getTime();
     boolean done = false;
     // truncate milliseconds
     int millisecs = val.get(Calendar.MILLISECOND);
     if (!round || millisecs < 500) {
         time = time - millisecs;
     }
     if (field == Calendar.SECOND) {
         done = true;
     }
     // truncate seconds
     int seconds = val.get(Calendar.SECOND);
     if (!done && (!round || seconds < 30)) {
         time = time - (seconds * 1000L);
     }
     if (field == Calendar.MINUTE) {
         done = true;
     }
     // truncate minutes
     int minutes = val.get(Calendar.MINUTE);
     if (!done && (!round || minutes < 30)) {
         time = time - (minutes * 60000L);
     }
     // reset time
     if (date.getTime() != time) {
         date.setTime(time);
         val.setTime(date);
     }
     // ----------------- Fix for LANG-59 ----------------------- END ----------------
     boolean roundUp = false;
     for (int i = 0; i < fields.length; i++) {
         for (int j = 0; j < fields[i].length; j++) {
             if (fields[i][j] == field) {
                 //This is our field... we stop looping
                 if (round && roundUp) {
                     if (field == DateUtils.SEMI_MONTH) {
                         //This is a special case that"s hard to generalize
                         //If the date is 1, we round up to 16, otherwise
                         //  we subtract 15 days and add 1 month
                         if (val.get(Calendar.DATE) == 1) {
                             val.add(Calendar.DATE, 15);
                         } else {
                             val.add(Calendar.DATE, -15);
                             val.add(Calendar.MONTH, 1);
                         }
                     } else {
                         //We need at add one to this field since the
                         //  last number causes us to round up
                         val.add(fields[i][0], 1);
                     }
                 }
                 return;
             }
         }
         //We have various fields that are not easy roundings
         int offset = 0;
         boolean offsetSet = false;
         //These are special types of fields that require different rounding rules
         switch (field) {
             case DateUtils.SEMI_MONTH:
                 if (fields[i][0] == Calendar.DATE) {
                     //If we"re going to drop the DATE field"s value,
                     //  we want to do this our own way.
                     //We need to subtrace 1 since the date has a minimum of 1
                     offset = val.get(Calendar.DATE) - 1;
                     //If we"re above 15 days adjustment, that means we"re in the
                     //  bottom half of the month and should stay accordingly.
                     if (offset >= 15) {
                         offset -= 15;
                     }
                     //Record whether we"re in the top or bottom half of that range
                     roundUp = offset > 7;
                     offsetSet = true;
                 }
                 break;
             case Calendar.AM_PM:
                 if (fields[i][0] == Calendar.HOUR_OF_DAY) {
                     //If we"re going to drop the HOUR field"s value,
                     //  we want to do this our own way.
                     offset = val.get(Calendar.HOUR_OF_DAY);
                     if (offset >= 12) {
                         offset -= 12;
                     }
                     roundUp = offset > 6;
                     offsetSet = true;
                 }
                 break;
         }
         if (!offsetSet) {
             int min = val.getActualMinimum(fields[i][0]);
             int max = val.getActualMaximum(fields[i][0]);
             //Calculate the offset from the minimum allowed value
             offset = val.get(fields[i][0]) - min;
             //Set roundUp if this is more than half way between the minimum and maximum
             roundUp = offset > ((max - min) / 2);
         }
         //We need to remove this field
         if (offset != 0) {
             val.set(fields[i][0], val.get(fields[i][0]) - offset);
         }
     }
     throw new IllegalArgumentException("The field " + field + " is not supported");
 }
 /**
*

Date iterator.

  */
 static class DateIterator implements Iterator {
     private final Calendar endFinal;
     private final Calendar spot;
     
     /**
      * Constructs a DateIterator that ranges from one date to another. 
      *
      * @param startFinal start date (inclusive)
      * @param endFinal end date (not inclusive)
      */
     DateIterator(Calendar startFinal, Calendar endFinal) {
         super();
         this.endFinal = endFinal;
         spot = startFinal;
         spot.add(Calendar.DATE, -1);
     }
     /**
      * Has the iterator not reached the end date yet?
      *
      * @return true if the iterator has yet to reach the end date
      */
     public boolean hasNext() {
         return spot.before(endFinal);
     }
     /**
      * Return the next calendar in the iteration
      *
      * @return Object calendar for the next date
      */
     public Object next() {
         if (spot.equals(endFinal)) {
             throw new RuntimeException();
         }
         spot.add(Calendar.DATE, 1);
         return spot.clone();
     }
     /**
      * Always throws UnsupportedOperationException.
      * 
      * @throws UnsupportedOperationException
      * @see java.util.Iterator#remove()
      */
     public void remove() {
         throw new UnsupportedOperationException();
     }
 }

}



 </source>