Provides Functors and Predicates that compare values of various types.
As of the 0.6 release, this package is in a state of transition. The forces
at work are
- the comparision mechanism in Java, ie, the Comparable and Comparator
interfaces.
- a desire to simplify the design so that a particular comparison method,
eg, Less, is embodied in a single class.
- a desire to preserve type-safety.
- a desire to preserve convenience of default constructors.
In the previous releases, there were two functors that provided for a
single comparison method -- one that was restricted to
Comparable arguments, and one that used (and therefore
required at construction) a Comparator. There was no
relationship between the restricted version, which was named for the
specific comparison operator (ie, Less.java) and the version
that required a Comparator, which was named with a
'-Comp' suffix (ie, LessComp.java).
To create a relationship between the two versions would have required
that the '-Comp' version be the base class. To derive the
-Comp version from the Comparable version would have
had the effect of imposing a restriction in the base class that the
derived class relaxes (this violates substitutabiliy).
Ideally, there would be one class: it would have to use a
Comparator as implementation in order to be universally
applicable, but the default constructor could provide some sort of
default Comparator. Unfortunately, there really is no useful
comparator that can be applied globally. The most common case that we
can support, however, would be that Comparable objects be
compare via their compareTo() method, as the
ComparableComparator does. For this to work, we would need
to ensure that the default constructor could only be called when the
parm type of the functor implements Comparable. Java cannot
enforce this restriction.
What we can do is define a subclass that has a more
restrictive bound than the base class. Throughout this package,
classes that need to support Comparable objects via a default
Comparator define a public static subclass that imposes the
additional generic bound and provides the correct default constructor.
I've created a convention by which all of the subclasses are named for
the bound they impose, so in this package, to use a comparison
operator for Comparable types requires the use of the
Comparable subclass. For example, to compare some arbitrary
class for which a Comparator is available, you might use a
Less object, and pass the Comparator at
construction. To compare String objects, you would use
Less.Comparable, whose default constructor passes a default
Comparator to the base Less constructor.
So, the upshot of all this is that in the next release, we will be
able to partially resolve the competing forces. The comparison
functors will support all types of java objects using both comparison
mechinisms with a single primary class for each comparison operation
(the nested subclasses are de-emphasized -- they are an unfortunate
implementation detail necessary to work around a limitation in generic
java). The final versions preserve type-safety and the cost in
inconvenience is not too great, as there is still a default
constructor, it has simply been moved to the nested subclass in order
to restrict its usage to appropriate generified types. In the next
release:
- The default constructor in the base classes will be removed.
- The '-Comp' versions will be removed.
Both of these changes are deferred for one release in order to avoid
breaking code without warning.
|