这是家庭作业,所以我更喜欢一些解释,而不仅仅是给我答案。
我有一个通用的Pair类,可以使用任何键值K和任何值V。
目标是编写通用方法:
public static <...> Collection<Pair<...>> sortPairCollection(Collection <Pair<....>> col)
唯一的另一个准则是K类型必须实现Comparable&lt; ...&gt ;.
经过一番挖掘,我看到人们推荐这样的东西:
public static Collection<Pair<?,?>> sortPairCollection(Collection<Pair<?,?>> col)
{
Collections.sort(col, new Comparator<Pair<?,?>>(){
@Override
public int compare(Pair<?, ?> x, Pair<?, ?> y) {
return (Integer)x.v() - (Integer)y.v();
}
});
}
但这对我不起作用,我得到一个错误,指出sort方法不适用于那些参数。我真的不知道从哪里开始。
答案 0 :(得分:6)
Collections.sort
仅适用于List
个实例,而不适用于一般Collections
。例如,对HashSet
进行排序没有意义。
其次,由于算术溢出,你应该避免在比较器中使用减法。最好使用Integer.compare
。
此外,返回类型为Collection<Pair<?,?>>
的方法必须返回一些内容。您可以返回col
,但在改变col
时,制作方法void
会更有意义。
另一点是看起来你的方法会抛出ClassCastException
,除非第二个类型参数是Integer
(我假设v()
有返回类型V
)。如果是这种情况,则无需为Pair<?, ?>
编写方法,因为您可以使用Pair<?, Integer>
。
最后,由于泛型在Java中的工作方式,您实际上无法使用当前签名传递List<Pair<String, Integer>>
,因为List<Pair<String, Integer>>
不是 a List<Pair<?, Integer>>
(请参阅this question或this one)。如果您希望能够这样做,则参数应该具有类型List<? extends Pair<?, Integer>>
。
修改强>
我现在意识到我没有真正回答这个问题。这个想法不是改变原始集合,而是返回一个新集合。此外,排序应该通过键而不是值来完成,因为K
必须实现Comparable
。
要使用compareTo
方法,您需要指明K extends Comparable
。这样做的方法是使用签名
public static <K extends Comparable<? super K>, V> Collection<Pair<K, V>> sortPairCollection(Collection<Pair<K, V>> col)
这有点令人满意 - 仿制药大大增加了方法签名的复杂性。
K extends Comparable<? super K>
表示可以将K
与其他K
进行比较。
但您仍然需要使用List
。您可以使用接受ArrayList
的{{1}}构造函数。
根据要求,我会留给您写正确的代码。
答案 1 :(得分:-1)
这是完整的程序:
public static <K extends Comparable<? super K>, V extends Comparable<? super V>> void sortPairCollection(List<Pair<K, V>> col){
Collections.sort(col, new Comparator<Pair<K,V>>(){
public int compare(Pair<K, V> o1, Pair<K, V> o2) {
int keyflag = o1.getValue().compareTo(o2.getValue()) == 0 ? o1.getKey().compareTo(o2.getKey()): o1.getValue().compareTo(o2.getValue()) ;
return keyflag;
}});
}