Range: Difference between revisions
mNo edit summary |
mNo edit summary |
||
Line 86: | Line 86: | ||
} | } | ||
</geshi> | </geshi> | ||
[[Category:Java]] |
Latest revision as of 02:31, 1 October 2007
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>