Range
Martin Fowler has written about the [Range Base Pattern] for representing a range of values. Here's a generic base class I wrote in Java which has the same basic functionality. I usually subclass this and add type specific methods.
<geshi lang="java"> /**
* A generic range. I would prefer to define this as Range<E extends Comparable<? super E>>, * but then pre 1.5 types can't be used with this. * Additionally, you run into hell when you have Base implements Comparable<Base> and want to have * Derived extends Base. Derived can't implement Comparable<Derived> because it's already defined differently * in the base class. */
public class Range<E extends Comparable> {
protected final E min; protected final E max;
public Range(E min, E max) {
GuardHelper.notNullMultiple(min, max);
validate(min, max);
this.min = min;
this.max = max;
}
protected void validate(E min, E max) {
if (min.compareTo(max) > 0) {
throw new IllegalArgumentException(min + " < " + max);
}
}
public boolean contains(E value) {
return value != null && min.compareTo(value) <= 0
&& max.compareTo(value) >= 0;
}
public E getMinimum() {
return min;
}
public E getMaximum() {
return max;
}
public int hashCode() {
return min.hashCode() + max.hashCode();
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Range range = (Range) o;
return max.equals(range.max) && min.equals(range.min); }
@Override
public String toString() {
return min + ".." + max;
}
} </geshi>
And of course the unit test <geshi lang="java"> public class RangeUnitTest extends UnitTestCase {
public void testContains() {
Range<Integer> range = new Range<Integer>(3, 5);
assertFalse(range.contains(2));
assertTrue(range.contains(3));
assertTrue(range.contains(4));
assertTrue(range.contains(5));
assertFalse(range.contains(6));
}
public void testCtor() {
try {
new Range<Integer>(5, 3);
failIfNoExceptionThrown();
} catch (IllegalArgumentException e) {
pass();
}
}
} </geshi>