Proposal: Comparables.isCommutativelyComparable

Aleksey Shipilev aleksey.shipilev at oracle.com
Sat Jun 8 20:04:16 UTC 2013


On 08.06.2013, at 23:51, Aleksey Shipilev <aleksey.shipilev at oracle.com> wrote:

> Hm, sounds interesting.
> 
> What's about yet another "factory"-like default in Comparator:
> 
> Comparator<C> Comparator.make(Class<C> klass)
>  - returns synthetic comparator using C.compareTo iff C implements Comparable<C>
>  - returns null otherwise

Err... "make" actually suggests we better do the zero-return Comparator if there is no Comparable<C> on the class. Which fits some of the things you want below.

> 
> That will naively instantiate the Comparator, but there is the possibility to reuse e.g. ClassValue to lazily associate the default comparator with the class.
> 
> -Aleksey.
> 
> On 08.06.2013, at 19:50, Doug Lea <dl at cs.oswego.edu> wrote:
> 
>> 
>> Suppose you have two objects, x and y, both of the same
>> type (x.getClass() == y.getClass()) and both known
>> to be instanceof Comparable.
>> 
>> Can you compare them? That is, can you safely call
>> (Comparable)x).compareTo(y);
>> 
>> Almost always, the answer is yes, because almost all
>> Comparable classes are of form "class C implements Comparable<C>"
>> 
>> But there's nothing about interface Comparable that forces
>> this to be true. It would be weird but legal if both
>> are of form, say, "class C implements Comparable<Byte>".
>> Which means that you cannot compare them to each other.
>> 
>> There's currently no direct way to check if you have a normal
>> commutative (bidirectionally applicable) pair of comparables.
>> 
>> It can be checked using reflection though, using mechanics
>> that are both messy and  slower than they might be if
>> implemented as a JDK utility method.
>> 
>> There a few possible API choices for how to do this.
>> 
>> The most basic is
>> 
>> boolean isCommutativelyComparable(Class<C?> c);
>> 
>> returning true if c represents a class form C implements Comparable<C>.
>> (It would be OK although a little annoying to use if it restricted
>> argument type to Class<Comparable<?>>.)
>> 
>> A more general one is:
>> 
>> Class<?> commutativelyComparableClassFor(Object x)
>> 
>> that returns a class C such that
>>  (x instanceof C) and (C implements Comparable<C>)
>> or null if there is no such class. The return type could
>> be strengthened to Class<Comparable<?>>
>> 
>> This allows use of the result to match up objects of
>> subclasses of commutatively comparable classes.
>> 
>> The most handy form is:
>> 
>> int compareIfCommutativelyComparable(Comparable x, Comparable y);
>> 
>> that returns compareTo result if both of same commutatively
>> comparable type, else 0.
>> 
>> Maybe this one is *too* handy though. It's not hard to
>> get the same effect manually given the above methods.
>> 
>> Does anyone have any thoughts about introducing at
>> least the first, and possibly the others into the
>> java.util.Comparables utility class? If so, there would
>> be a few immediate usages within JDK.
>> 
>> I'm surprised that this hasn't come up for consideration
>> before. Or maybe I haven't noticed previous discussions?
>> 
>> -Doug
>> 
>> 
>> 



More information about the core-libs-dev mailing list