Reputation: 31211
Create a Map
that can be sorted by value.
The code executes as expected, but does not compile cleanly:
public class SortableValueMap<K, V> extends LinkedHashMap<K, V> {
...
public void sortByValue() {
...
Collections.sort( list, new Comparator<Map.Entry>() {
public int compare( Map.Entry entry1, Map.Entry entry2 ) {
return ((Comparable)entry1.getValue()).compareTo( entry2.getValue() );
}
});
...
The syntax for passing Comparable
as a generic parameter along to the Map.Entry<K, V>
(where V
must be Comparable
?) -- so that the (Comparable)
typecast shown in the warning can be dropped -- eludes me.
Compiler's cantankerous complaint:
SortableValueMap.java:24: warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
return ((Comparable)entry1.getValue()).compareTo( entry2.getValue() );
How can the code be changed to compile without any warnings (without suppressing them while compiling with -Xlint:unchecked
)?
Thank you!
Upvotes: 0
Views: 2404
Reputation: 87593
The syntax for passing Comparable as a generic parameter along to the Map.Entry (where V must be Comparable?) -- so that the (Comparable) typecast shown in the warning can be dropped -- eludes me.
How about:
public class SortableValueMap <K, V extends Comparable<V>> extends LinkedHashMap<K, V> {
...
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> entry1, Map.Entry<K, V> entry2) {
return (entry1.getValue()).compareTo(entry2.getValue());
}
});
but this may be better, depending on your intent:
public class SortableValueMap <K, V extends Comparable<? super V>> extends LinkedHashMap<K, V> { ...
See http://download.oracle.com/javase/tutorial/extra/generics/morefun.html
It isn't necessary that T be comparable to exactly itself. All that's required is that T be comparable to one of its supertypes. This give us:
public static <T extends Comparable<? super T>> max(Collection<T> coll)
... This reasoning applies to almost any usage of Comparable that is intended to work for arbitrary types: You always want to use
Comparable <? super T>
. ...
Upvotes: 1
Reputation: 301
The value should be a subclass of comparable.
SortableValueMap<K, V extends Comparable>
Try the above.
Upvotes: 2
Reputation: 14222
Declare the V
type to extend the Comparable<V>
interface. That way, you can remove the cast of the Map.Entry
objects down to (Comparable)
and use the inferred type instead:
public class SortableValueMap<K, V extends Comparable<V>>
extends LinkedHashMap<K, V> {
....
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> entry1, Map.Entry<K, V> entry2) {
return entry1.getValue().compareTo(entry2.getValue());
}
});
Upvotes: 6