【问题标题】:How to sort a Collection of generic Pairs如何对泛型对的集合进行排序
【发布时间】:2016-04-03 14:45:48
【问题描述】:

这是家庭作业,所以我更希望得到一些解释,而不是只给我答案。

我有一个通用的 Pair 类,它可以采用任何键值 K 和任何值 V。

目标是写一个泛型方法:

public static <...> Collection<Pair<...>> sortPairCollection(Collection <Pair<....>> col)

唯一的其他准则是 K 类型必须实现 Comparable<...>。

经过一番挖掘,我看到人们推荐这样的东西:

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();
        }
    });
}

但这对我不起作用,我收到一条错误消息,指出排序方法不适用于这些参数。我真的不知道从这里去哪里。

【问题讨论】:

    标签: java sorting


    【解决方案1】:

    Collections.sort 仅适用于 List 实例,不适用于一般 Collections。例如,对HashSet 进行排序是没有意义的。

    其次,由于算术溢出,您应该避免在这样的比较器中使用减法。使用Integer.compare 总是更好。

    此外,返回类型为Collection&lt;Pair&lt;?,?&gt;&gt; 的方法必须返回一些内容。你可以返回col,但是当你改变col时,使用void方法更有意义。

    另外一点是,除非第二个类型参数是 Integer(我假设 v() 的返回类型为 V),否则您的方法似乎会抛出 ClassCastException。如果是这种情况,那么为 Pair&lt;?, ?&gt; 编写方法是没有意义的,因为您可以使用 Pair&lt;?, Integer&gt;

    最后,由于泛型在 Java 中的工作方式,您实际上无法使用您当前的签名传入 List&lt;Pair&lt;String, Integer&gt;&gt;,因为 List&lt;Pair&lt;String, Integer&gt;&gt; 不是 @987654340 @(见this questionthis one)。如果您希望能够做到这一点,则参数的类型应为 List&lt;? extends Pair&lt;?, Integer&gt;&gt;

    编辑

    我现在意识到我还没有真正回答这个问题。这个想法不是改变原始集合,而是返回一个新集合。此外,排序应该通过键而不是值来完成,因为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&lt;? super K&gt; 表示Ks 可以与其他Ks 进行比较。

    不过,您仍然需要使用List。您可以使用接受CollectionArrayList 构造函数。

    根据要求,我将由您来编写正确的代码。

    【讨论】:

    • 另外,该方法声明返回Collection&lt;Pair&lt;?,?&gt;&gt;,但实际上没有。
    • @Tunaki 你说得对。自从我试图先弄清楚排序后,我一直没有解决这个问题。
    • @Tunaki 谢谢,我错过了。
    • 我对这个答案有两个问题。 1)你没有覆盖“K类型必须实现Comparable<...>”。对我来说,这意味着排序应该按键对对进行排序,而不是按值。 2)如果“目标是写[显示的]泛型方法”,你可以做到。它返回Collection 的原因是它不应该改变参数,这也是为什么参数可以是Collection 而不是List
    • @Andreas 你是对的。我实际上并没有注意到关于K 的部分。我忙于分析代码,我错过了问题的全部要点。我会编辑。
    【解决方案2】:

    这是完整的程序:

    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;
    
                }});
    
        }
    

    【讨论】:

    • 在问题中明确说明:所以我更喜欢一些解释,而不是仅仅给我答案。所以这不是答案
    猜你喜欢
    • 2011-04-04
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    相关资源
    最近更新 更多