From: Roedy Green on
If Comparable were just an ordinary interface you could say things
like this:

Comparable a = "abc";
Comparable b = Double.valueOf ( 10.0d );
Comparable c = Double.valueOf ( 12.9d );


int x = b.compareTo( c );

But generics butt in and it seems to be impossible to keep around
arrays of Comparables for sorting columns.

One way, which I find ugly is to sort Objects instead of Comparables
then cast them to specific types before calling compareTo. That should
not be necessary. All the JVM should need to know at compile time is
that a reference is implements comparable.



--
Roedy Green Canadian Mind Products
http://mindprod.com

Imagine an architect who would never admit to making sketches, blueprints or erecting scaffolds. In his view, the finished building speaks for itself. How could a young architect learn from such a man? Mathematicians traditionally refuse ever to disclose the intuitions that lead them to a conjecture, or the empirical tests to see if it were likely true, or the initial proofs. They are like chefs who refuse to disclose their recipes, ingredients or techniques.
From: Thomas Pornin on
According to Roedy Green <see_website(a)mindprod.com.invalid>:
> If Comparable were just an ordinary interface you could say things
> like this:
>
> Comparable a = "abc";
> Comparable b = Double.valueOf ( 10.0d );
> Comparable c = Double.valueOf ( 12.9d );
>
> int x = b.compareTo( c );

Well, you can. Try it; it compiles and runs.

The Java compiler grumps a bit because it uses runtime typing.
Comparable.compareTo() throws a ClassCastException on type mismatch;
generics are meant to let the compiler check such things, rather than
issuing a runtime exception at runtime. In your situation, you have to
"know" which instances of Comparable can be compared to each other and
which cannot.

Nevertheless, Java supports dynamic typing and the raw type is not
deprecated in any way. Generics are a handy tools, not a mandatory
regulation.


--Thomas Pornin
From: Lew on
Thomas Pornin wrote:
> According to Roedy Green <see_website(a)mindprod.com.invalid>:
>> If Comparable were just an ordinary interface you could say things
>> like this:
>>
>> Comparable a = "abc";
>> Comparable b = Double.valueOf ( 10.0d );
>> Comparable c = Double.valueOf ( 12.9d );
>>
>> int x = b.compareTo( c );
>
> Well, you can. Try it; it compiles and runs.
>
> The Java compiler grumps a bit because it uses runtime typing.
> Comparable.compareTo() throws a ClassCastException on type mismatch;
> generics are meant to let the compiler check such things, rather than
> issuing a runtime exception at runtime. In your situation, you have to
> "know" which instances of Comparable can be compared to each other and
> which cannot.
>
> Nevertheless, Java supports dynamic typing and the raw type is not
> deprecated in any way. Generics are a handy tools, not a mandatory
> regulation.

You can do it generically, too, if you write a helper class or method that
takes the type of the column you want to sort (see the original post), either
at compile time or with a Class<T> run-time type token. You get your type
safety at a cost of a slight increase in verbosity.

You can also declare
Comparable <String> a = "abc";
Comparable <Double> b = Double.valueOf ( 10.0d );
Comparable <Double> c = Double.valueOf ( 12.9d );
int x = b.compareTo( c );

Untried:
public static <T> int compare( Comparable <T> a, Comparable <T> b )
{
return a.compareTo( b );
}

I'm not even sure you can call that more verbose since you add a method but
subtract the variable declarations in the caller.

--
Lew
From: Roedy Green on
On 24 Feb 2010 12:49:17 GMT, Thomas Pornin <pornin(a)bolet.org> wrote,
quoted or indirectly quoted someone who said :

>In your situation, you have to
>"know" which instances of Comparable can be compared to each other and
>which cannot.

In the old days, so long as each column contained compatible things,
you could just use Comparable.compareTo and all would automagically
sort itself out. Today you get squawking if you do it because, for
example, String no longer implements Comparable, it implements
Comparable<String> which will not cast to Comparable or
Comparable<Object>
--
Roedy Green Canadian Mind Products
http://mindprod.com

The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at or repair.
~ Douglas Adams (born: 1952-03-11 died: 2001-05-11 at age: 49)
From: markspace on
Roedy Green wrote:

> If Comparable were just an ordinary interface you could say things
....
> But generics butt in and it seems to be impossible to keep around
> arrays of Comparables for sorting columns.


The problem here is that the Comparable interface is designed for the
class itself to compare to other objects. If you were the one
implementing this method, how many classes would you want to compare it
to?

Using your example of comparing Strings and Double, let's look at String
method:

public int compareTo( Object o ) {
if( o instanceof String )
... normal string compare...
else if( o instanceof Double )
... compare String to Double...
else if( o instanceof Integer )
... how many of these do you want?


It just goes on and on. Frankly, I think your question lacks any sort
of critical thought. It's pretty obvious what would happen if one
actually tried to implement your idea. Not good things.

And of course, this code would have to be duplicated inside Double, and
Integer, and every other class that you wanted to compare to. That the
real issue for me. It's just a stinky idea.


>
> One way, which I find ugly is to sort Objects instead of Comparables


Ugly is as ugly does, I suppose. Maybe don't use Object? A little
effort wouldn't hurt here.

Let's see, off the top of my head. We don't want to compare Objects, so
we do want to make our own type.

public interface MyColumnType {}

It's just a marker interface for now. So we want to compare Strings,
but we can't extend String. We'll have to use composition.
Fortuneately, there's a string-like interface, CharacterSequence that
will help

public class MyStringType implements CharacterSequence, MyColumnType
private final String value;
public MyStringType( String v ) { value = v; }
....
}

We can't extend Double either, but there is a common Number class we can
use:

public class MyNumericType extends Number implements MyColumnType
private final Number value;
public MyNumericType( Number n ) { value = n; }
...
}

Now we can use a Comparator to implement the actual comparison

public class MyColumnComparator implements Comparator<MyColumnType>
{
public void compare(MyColumnTye o1, MyColumnTye o2 ) {

.. implement here..

}
}

Now at least it looks like someone made some sort of effort. I don't
have an algorithm for comparing Strings and Numbers for you, but then I
don't know how you want to compare them. It's a critical detail you
conveniently left out. I don't think there is a standard way of
comparing them, do you? So I'll just leave the rest of it to you then.



 |  Next  |  Last
Pages: 1 2 3 4
Prev: Java crash
Next: NullPointerException