001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002// The Molly framework is freely distributable under the terms of an 003// MIT-style license. For details, see the molly pages web site at: 004// http://www.mollypages.org/. Use, modify, have fun ! 005 006package fc.util; 007 008import java.util.*; 009 010/** 011A range of integral values. 012<p> 013Note, many methods in this particular class have the same 014signatures as in the apache <tt>commons.lang</tt> package but the 015<tt>implementation</tt> was strictly clean-room. 016<p> 017Thread Safety: This class is not thread safe in the face of any 018concurrent modification (via changing the start/end numbers or 019union/intersection operations). 020 021@author hursh jain 022**/ 023public class NumberRange extends Range 024{ 025long start; 026long end; 027 028/** 029Constructs a number range between the specified 030start and end numbers (both inclusive). 031 032@throws IllegalArgumentException 033 if the end number is lesser (via a <tt><</tt> comparison) 034 than the start number (equal to the start number is ok) 035**/ 036public NumberRange(long start, long end) 037 { 038 Argcheck.istrue(start <= end, "end number lesser than start number in the specified range, start=["+start+"], end=["+end+"]"); 039 this.start = start; 040 this.end = end; 041 } 042 043/** Get the start number for this number range **/ 044public long getStart() 045 { 046 return start; 047 } 048 049/** 050Get the end number for this number range. 051**/ 052public long getEnd() 053 { 054 return end; 055 } 056 057 058/** Is the passed in number inside this range **/ 059public boolean inRange(long c) 060 { 061 boolean result = (c >= start) && (c <= end); 062 063 if (negated) 064 return !result; 065 else 066 return result; 067 } 068 069/** 070Sets the end number for this number range 071 072@param c the end number 073@throws IllegalArgumentException 074 if the end number is lesser (via a <tt><</tt> comparison) 075 than the current start number (equal to the start number is 076 ok) 077**/ 078public void setEnd(long c) 079 { 080 Argcheck.istrue(start <= c, "end number lesser than start number in the specified range, start=["+start+"], specified end=["+c+"]"); 081 end = c; 082 } 083 084/** Set the start number for this number range 085 086@throws IllegalArgumentException 087 if the start number is greater (via a <tt>></tt> comparison) 088 than the current end number (equal to the end number is 089 ok) 090**/ 091public void setStart(long c) 092 { 093 Argcheck.istrue(c <= end, "start number greater than end number in the specified range, end=["+end+"], specified start=["+c+"]"); 094 start = c; 095 } 096 097/** Returns the size of this range which is calculated as the 098<tt>(endnumber - startnumber) + 1</tt> - i.e., the number of 099slots in this range, start and end inclusive. 100**/ 101public long getSize() { 102 return (end - start) + 1; 103 } 104 105 106/** Output a string representation of the number range **/ 107public java.lang.String toString() 108 { 109 String str = "NumberRange:["; 110 if (isNegated()) 111 str += "^"; 112 113 if (start >= 0) 114 str += start; 115 else 116 str += "(" + start + ")"; 117 118 str += "<->"; 119 120 if (end >= 0) 121 str += end ; 122 else 123 str += "(" + end + ")"; 124 125 str += "]"; 126 return str; 127 } 128 129public boolean equals(Object obj) 130 { 131 if (! (obj instanceof NumberRange)) 132 return false; 133 NumberRange other = (NumberRange) obj; 134 return (this.start == other.start && 135 this.end == other.end); 136 } 137 138public int hashCode() { 139 return (int) getSize(); 140 } 141 142 143public static void main(String[] args) 144 { 145 NumberRange r = new NumberRange(-10, 10); 146 147 System.out.println("constructed range:" + r); 148 System.out.println("Range size=" + r.getSize()); 149 150 NumberRange r2 = new NumberRange(-10, 10); 151 System.out.println("Constructed range2=" + r2); 152 NumberRange r3 = new NumberRange(-10, 9); 153 System.out.println("Constructed range3=" + r3); 154 155 System.out.println(""); 156 System.out.println("r.equals(r2)="+r.equals(r2)); 157 System.out.println("r.equals(r3)="+r.equals(r3)); 158 159 System.out.println("r.hashCode="+r.hashCode()); 160 System.out.println("r2.hashCode="+r2.hashCode()); 161 System.out.println("r3.hashCode="+r3.hashCode()); 162 163 164 //normal 165 test(r); 166 167 //negate 168 r.setNegated(true); 169 System.out.println("setting the range to be negated:" + r); 170 test(r); 171 172 System.out.println("the following should throw an exception"); 173 r = new NumberRange(5, 0); 174 } 175 176private static void test(NumberRange r) 177 { 178 System.out.println("0 in range:" + r.inRange(0)); 179 System.out.println("1 in range:" + r.inRange(1)); 180 System.out.println("10 in range:" + r.inRange(10)); 181 System.out.println("11 in range:" + r.inRange(11)); 182 System.out.println("-1 in range:" + r.inRange(-1)); 183 System.out.println("-10 in range:" + r.inRange(-10)); 184 System.out.println("-11 in range:" + r.inRange(-11)); 185 } 186 187} //~class NumberRange