如何对泛型对的集合进行排序

时间:2016-04-03 14:45:49

标签: java sorting

这是家庭作业,所以我更喜欢一些解释,而不仅仅是给我答案。

我有一个通用的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方法不适用于那些参数。我真的不知道从哪里开始。

2 个答案:

答案 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 questionthis 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;

            }});

    }