我有一个小程序,应该根据它的值对地图进行排序。以下是我到目前为止的情况:
public static <K, V extends Comparable< ? extends V>> Map<K, V>
sortByValues(final Map <K, V> mapToSort)
{
List<Map.Entry<K, V>> entries =
new ArrayList<Map.Entry<K, V>>(mapToSort.size());
entries.addAll(mapToSort.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K, V>>()
{
public int compare(
final Map.Entry<K, V> entry1,
final Map.Entry<K, V> entry2)
{
return entry1.getValue().compareTo(entry2.getValue());
}
});
Map<K, V> sortedMap = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : entries)
{
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
我希望我的通用值V可以与 V或至少是V 的子类的任何内容相媲美。
我的代码片段出现以下错误:
public static <K, V extends Comparable< ? extends V>>
绑定不匹配:方法compareTo(? 扩展V)类型V不适用 对于论证(V)。通配符 参数?延伸V没有更低 绑定,可能实际上更多 限制比参数V
如何限制更多?
如果我将声明更改为:
public static <K, V extends Comparable< ? super V>>
然后没有错误。但这不是我想要的。
我的一个解决方法是,我可以将声明更改为:
public static <K, V extends Comparable<V>>
但是这样做我失去了灵活性,因为我无法传递一个Map,它的值实现了Comparable与它自己的子类。
为这么长的问题道歉。提前谢谢。
答案 0 :(得分:4)
我认为你的第二个选择,即
public static <K, V extends Comparable<? super V>>
是通往的方式。我认为这是因为你写的时候
public static <K, V extends Comparable<C extends V>>
你基本上说你希望能够将V
的任何实例与C
的任何实例进行比较。但是这里缺少的是,因为你想在内部调用Collections.sort(..)
,你还必须能够将C
的任何实例与V
的任何实例进行比较。但是泛型不表达这一点,理所当然编译器会抱怨。
基本上,要排序某些值(至少使用Collections.sort(..)
),它们必须相互可比较,但您设想的通用限制只能保证您可以在一个方向进行比较。
答案 1 :(得分:3)
实现与自身的子类Comparable。
这是“糟糕的设计”:作为一般规则,类不应该知道它们的子类。
您有什么用例?
我认为public static <K, V extends Comparable<V>>
没问题。
答案 2 :(得分:0)
我认为您希望V成为某种类型的扩展。尝试在模板声明中添加临时类型T,如下所示:
public static <K, T extends Comparable<T>, V extends T> Map<K, V>
sortByValues(final Map <K, V> mapToSort)
其他一切都保持不变。如果你不是那个意思,那就是你的所有可比对象都将成为V的子类型,那么public static <K, V extends Comparable<V>>
是有意义的,因为从V的角度来看,覆盖了比较的V的子类将会使用与V具有的compareTo方法相同的签名调用compareTo方法。即,V声明的compareTo方法将被调用(但它可能是V的子类中被重写的定义)。因此,V extends Comparable<V>
就足够了。我希望我已经说清楚了。