Often code has a bad smell, then it gets time to replace custom lines by common patterns. Sometimes it even makes sense to even replace a single line of code by a class just wrapping that single line (which actually increases code size), if that makes readers better understand what the code does. Unfortunately often such patterns are publicly known but do not exist as ready to use classes in the JRE, so one needs to write them again and again. To not make people having to type again and again, I typically upload mine to the web, so everybody is free to share it. One example is the Range pattern (see Martin FOWLER's web site for a deeper introduction to that pattern).

The Range Pattern

In short, a Range is something that is described by an upper and lower bound. Sometimes, a range is open, i. e. it only has one bound or even none at all. Typically, ranges are used to check single values against them, like "Is my birthday while I am on holidays?" (the holidays are a range described by the first and last date, the birthday is a single date). Or, "Is this car in the wanted price range (neither too crappy, i. e. cheap, nor too expensive)?" (the price range is described by the lowest sensible price and the maximum amount you want to pay, the actual price of a specific car is a single price). So, a range is a pattern, and it is independent of the value's type. It fits nicely to implement it as a generic class, as it hell to write that if...&&...||...&&... again and again, particularly with possibly open ranges (open ranges make things rather complex). Sad but true, there is no such class in the JRE, and Oracle did not pick up my RFE to add one so far.

The Generic Range<T> Class

So I just wrote a class that fills this gap. Since it is generic, you can safely use it with any information type you like - Integers, Dates, Prices, anything that implements the Comparable maker interface to indicate that it can be compared against a boundary. The class is able to deal with open ranges by passing null as a limit, but it doesn't allow to check a null value against its borders (since the result wouldn't be intuitive). If you need a Range class for your GPL'ed project, just download it from my web site: http://www.headcrashing.eu.

What Next?

If you have any ideas what the Range class should be able to do (like being Comparable on its own, intersect or merge other Range instances, etc.), just add a comment. If you have a finished algorithm or test case, this would be even better. I will update the class, so everybody can share the benefit.

Regards
Markus

Updates

       
  1. Version 1.0.1: Improved java docs regarding open ranges.
  2.    
  3. Version 1.0.2: Fixed bug with Range<T>.contains(T) returning wrong results due to assumption that Comparable<T>.compareTo(T) would return only -1 and 1, while it actually can be -N and N.
  4.    
  5. Version 1.1.0: Merged anonymous author's contribution Range<T>.contains(Range<T>) to check whether a range is within another range. This is useful e. g. if your like to know whether a meeting is within someone's free time in a calendar (the meeting entry in the calendar has a Range<Date, Date>, also has the free time entry). Also uploaded unit test for Range<T> class to support more contributions.
  6.    
  7. Version 1.2.0: Merged anonymous author's contribution Range<T>.overlaps(Range<T>) to check whether a range overlaps (intersects, touches) another range. This is useful e. g. if you like to know whether a meeting will run over the start of another meeting in a calendar (the meeting entries in the calendar have Range<Date, Date>s).
  8.    
  9. Version 1.2.1: Fixed bug with Range<T>(T, T) not reporting interchanged limits due to assumption that Comparable<T>.compareTo(T) would return only -1 and 1, while it actually can be -N and N.
  10.    
  11. Version 1.2.2: Uploaded to Maven Central, so using the class is as simple as adding the following dependency to a project's POM: <dependency><groupId>eu.headcrashing.treasure-chest</groupId><artifactId>RangeClass</artifactId><version>[1.2.2, 2)</version></dependency>

An overview of all my publications, presentations, code snippets or complete products, can be found on my personal web site Head Crashing Informatics.