Prev: Java crash
Next: NullPointerException
From: Roedy Green on 26 Feb 2010 06:13 On Wed, 24 Feb 2010 13:24:29 -0500, Lew <noone(a)lewscanon.com> wrote, quoted or indirectly quoted someone who said : > String no longer implements Comparable, it implements >>> Comparable<String> which will not cast to Comparable or >>> Comparable<Object> > >markspace wrote: >> I'm pretty sure String will cast to Comparable<String>. > >Of course it will. I don't know where the notion comes from that 'String' >does not implement 'Comparable<String>', when it says right in the Javadocs >that it does. String DOES implement Comparable<String>. Nobody claimed it did not. The problem is when you want to use the Comparable the way you did before generics, where you compare any two Objects and the JVM sorted out which compareTo method to use depending on the type of the Object. You can't cast a Comparable<String> to a 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: Roedy Green on 26 Feb 2010 06:29 On Wed, 24 Feb 2010 13:24:29 -0500, Lew <noone(a)lewscanon.com> wrote, quoted or indirectly quoted someone who said : > I mean, what >if you put an Float and a Double, say, into the same column in "the old days"? > What would happen? A Comparable in the old days had an Object parameter, with no generic narrowing guarantee. Often code would check that the object was of the desired type before the compare. If you look at the code, String.compareTo now has the signature int compareTo( String ). Ditto public int compareTo(String anotherString) I am puzzled here. It looks as if String.compareTo( Object ) has disappeared. But how then could old code run under the new JVMs? In the old days, all you had to do was make sure your columns had compatible objecs in them, and you could compare any column with compareTo. OO overrides performed the necessary magic. You did not need different code for different types of column. The problem with generics is it forces you to pretend to know at compile time things you don't know until run time. -- 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: Roedy Green on 26 Feb 2010 06:50 On Wed, 24 Feb 2010 10:10:46 -0800, markspace <nospam(a)nowhere.com> wrote, quoted or indirectly quoted someone who said : > >Using your example of comparing Strings and Double, let's look at String >method: That is not what I said. The columns must have COMPATIBLE types in them. e.g. all Strings, all Doubles, though different columns might have different types. I just don't want a big case clause to sort a column depending on the type that is currently in it. It is a reversion to C. Here some code from CSVSort that stinks. /** * Sort on arbitrary list of columns. * Defines default the sort order for SortableCSVRow Objects. * Compare this SortableCSVRow with another SortableCSVRow with JDK 1.5+ generics. * Compares key then key2 then key3. * Informally, returns (this-other) or +ve if this is more positive than other. * * @param other other SortableCSVRow to compare with this one * * @return +ve if this>other, 0 if this==other, -ve if this<other */ public final int compareTo( SortableCSVRow other ) { int diff; // sort over keys till find a non-tie. for ( int i = 0; i < CSVSort.this.countOfColsToSort; i++ ) { switch ( CSVSort.this.sortTypes[ i ] ) { case 's': // case sensitive, default compare String if ( CSVSort.this.isAscendings[ i ] ) { /* ascending */ diff = ( ( String ) this.keys[ i ] ).compareTo( ( String ) other.keys[ i ] ); } else { /* descending */ diff = ( ( String ) other.keys[ i ] ).compareTo( ( String ) other.keys[ i ] ); } break; case 'i': // case insensitive if ( CSVSort.this.isAscendings[ i ] ) { /* ascending */ diff = ( ( String ) this.keys[ i ] ).compareToIgnoreCase( ( String ) other.keys[ i ] ); } else { /* descending */ diff = ( ( String ) other.keys[ i ] ).compareToIgnoreCase( ( String ) this.keys[ i ] ); } break; case 'n': // represented as Double if ( CSVSort.this.isAscendings[ i ] ) { /* ascending */ diff = ( ( Double ) this.keys[ i ] ).compareTo( ( Double ) other.keys[ i ] ); } else { /* descending */ diff = ( ( Double ) other.keys[ i ] ).compareTo( ( Double ) this.keys[ i ] ); } break; case 'x': // represented as Long if ( CSVSort.this.isAscendings[ i ] ) { /* ascending */ diff = ( ( Long ) this.keys[ i ] ).compareTo( ( Long ) other.keys[ i ] ); } else { /* descending */ diff = ( ( Long ) this.keys[ i ] ).compareTo( ( Long ) other.keys[ i ] ); } break; default: throw new IllegalArgumentException( "Program bug: invalid SortType: " + sortTypes[ i ] ); } if ( diff != 0 ) { return diff; } } return 0; } -- 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: Joshua Cranmer on 26 Feb 2010 07:58 On 02/26/2010 06:29 AM, Roedy Green wrote: > I am puzzled here. It looks as if String.compareTo( Object ) has > disappeared. But how then could old code run under the new JVMs? It's an automatically-generated bridge method. You can use javap to convince yourself that it exists. -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth
From: Alessio Stalla on 26 Feb 2010 10:30
On Feb 26, 12:50 pm, Roedy Green <see_webs...(a)mindprod.com.invalid> wrote: > On Wed, 24 Feb 2010 10:10:46 -0800, markspace <nos...(a)nowhere.com> > wrote, quoted or indirectly quoted someone who said : > > > > >Using your example of comparing Strings and Double, let's look at String > >method: > > That is not what I said. The columns must have COMPATIBLE types in > them. e.g. all Strings, all Doubles, though different columns might > have different types. > > I just don't want a big case clause to sort a column depending on the > type that is currently in it. It is a reversion to C. > > Here some code from CSVSort that stinks. > > /** > * Sort on arbitrary list of columns. > * Defines default the sort order for SortableCSVRow Objects. > * Compare this SortableCSVRow with another SortableCSVRow > with JDK 1.5+ generics. > * Compares key then key2 then key3. > * Informally, returns (this-other) or +ve if this is more > positive than other. > * > * @param other other SortableCSVRow to compare with this one > * > * @return +ve if this>other, 0 if this==other, -ve if > this<other > */ > public final int compareTo( SortableCSVRow other ) > { > int diff; > // sort over keys till find a non-tie. > for ( int i = 0; i < CSVSort.this.countOfColsToSort; i++ ) > { > switch ( CSVSort.this.sortTypes[ i ] ) > { > case 's': // case sensitive, default compare > String > > if ( CSVSort.this.isAscendings[ i ] ) > { > /* ascending */ > diff = ( ( String ) this.keys[ i ] > ).compareTo( ( String ) other.keys[ i ] ); > } > else > { > /* descending */ > diff = ( ( String ) other.keys[ i ] > ).compareTo( ( String ) other.keys[ i ] ); > } > break; > > case 'i': > // case insensitive > if ( CSVSort.this.isAscendings[ i ] ) > { > /* ascending */ > diff = ( ( String ) this.keys[ i ] > ).compareToIgnoreCase( ( String ) other.keys[ i ] ); > } > else > { > /* descending */ > diff = ( ( String ) other.keys[ i ] > ).compareToIgnoreCase( ( String ) this.keys[ i ] ); > } > break; > > case 'n': // represented as Double > > if ( CSVSort.this.isAscendings[ i ] ) > { > /* ascending */ > diff = ( ( Double ) this.keys[ i ] > ).compareTo( ( Double ) other.keys[ i ] ); > } > else > { > /* descending */ > diff = ( ( Double ) other.keys[ i ] > ).compareTo( ( Double ) this.keys[ i ] ); > } > break; > > case 'x': // represented as Long > > if ( CSVSort.this.isAscendings[ i ] ) > { > /* ascending */ > diff = ( ( Long ) this.keys[ i ] > ).compareTo( ( Long ) other.keys[ i ] ); > } > else > { > /* descending */ > diff = ( ( Long ) this.keys[ i ] > ).compareTo( ( Long ) other.keys[ i ] ); > } > break; > > default: > throw new IllegalArgumentException( "Program > bug: invalid SortType: " + sortTypes[ i ] ); > } > if ( diff != 0 ) > { > return diff; > } > } > > return 0; > } You're not forced to use that idiom. Rather than casting to concrete types, cast to Comparable: if ( CSVSort.this.isAscendings[ i ] ) { /* ascending */ diff = ( ( Comparable ) this.keys[ i ] ).compareTo( other.keys[ i ] ); } else { /* descending */ diff = ( ( Comparable ) this.keys[ i ] ).compareTo( other.keys[ i ] ); } you will of course get unchecked warnings, because the compiler won't be able to enforce that compareTo is called on compatible types. That's a case when the SuppressWarnings annotation is necessary. Alessio |