Java中的可比较和比较器接口

我想写一个通用的Pair类,它有两个成员:key和value.这个类的唯一要求是key和value都应该实现Comparable接口,否则Pair类不会接受它们作为类型参数.
首先,我这样编码:

public class Pair<T1 extends Comparable, T2 extends Comparable>

但是JDK 1.6编译器会生成关于此的警告:

Comparable is a raw type. References to generic type Comparable<T> should be parameterized

然后我尝试添加类型参数,现在代码如下所示:

public class Pair<T1 extends Comparable<? extends Object>,
                  T2 extends Comparable<? extends Object>>

现在一切顺利,直到我尝试为Pair生成Comparator.(以下代码在Pair类中)

public final Comparator<Pair<T1, T2>> KEY_COMPARATOR = new Comparator<Pair<T1, T2>>() {
        public int compare(Pair<T1, T2> first, Pair<T1, T2> second) {
            *first.getKey().compareTo(second.getKey());*
            return 0;
        }
    };

代码first.getKey().compareTo(second.getKey());会产生错误说:

The method compareTo(capture#1-of ? extends Object) in the type Comparable<capture#1-of ? extends Object> is not applicable for the  arguments (T1)

任何人都知道这个错误消息是什么意思?
欢迎任何有关此主题的提示.

更新:
这是完整的代码:

public class Pair<T1 extends Comparable<? extends Object>, T2 extends Comparable<? extends Object>> {
    private T1 key;
    private T2 value;

    public static int ascending = 1;
    public final Comparator<Pair<T1, T2>> KEY_COMPARATOR = new Comparator<Pair<T1, T2>>() {
        public int compare(Pair<T1, T2> first, Pair<T1, T2> second) {
            int cmp = first.getKey().compareTo((T1)(second.getKey()));
            if (cmp > 0)  return ascending;
            return -ascending;
        }
    };
}

@MarvinLabs你能解释一下为什么编译器无法确保将对象与同类型的其他对象进行比较的原因.在上面的代码中,second.getKey()返回T1类型,它与first.getKey()的类型相同

最佳答案
让我们先看一下界面设计.

public interface Comparable<T> { 

   public int compareTo(T o);

} 

我们必须说这是很典型的.因此,如果我们的课程需要实现它,我们就这样做.

pubilc class ICanComparteWithMyself implements Comparable<ICanComparteWithMyself> { 

public int compareTo(ICanComparteWithMyselfo)    
   //code for compration
} 

当我们看到通用参数类型时,确定我们将要操作的内容,因此对于泛型,我们以相同的方式操作

public class ICanCompareMyGeneric<T> implements Comparable<T> {

   public int compareTo(T o)    
       //code for compration
    } 
}

在你的情况下,我们希望它确保泛型参数实现是自己的Comparable,为此我们需要这样做

public class MyGenericCanCompareToItself<T extends Comparable<T>> { 

}

我们可以看到,这是很常见的使用方法.预期(或不是)的限制是我们可以处理为其自身类型实现Comparable的类.如果我们有

 public class ICanCompareStrings implements Comparable<String> {
      public int compareTo(String o)    
           //code for compration
      }
 }

因此,对于类MyGenericCanCompareToItself作为泛型参数,我们可以使用类public MyGenericCanCompareToItself但不能使用ICanCompareStrings.

编辑:

因此,当我们涵盖基础知识时,我们可以解决您的问题

您的班级描述如下所示

公共类对< T1扩展Comparable<? extends Object>,T2扩展Comparable<? extends Object>>

这没有太多的感觉,因为与<?>相同.

这个描述说:

I am a Pair class, that work with two generic parameters, that can use comparison over something that I do not know.

使用这段代码,你不能在通用参数不知道之前进展,然后在那里操作,最终得到这样的东西.

first.getKey.compareTo(NULL);

这就是为什么你编写的代码在你尝试强制转换时不能编译,期望的类型为null.

要更改它,您需要确定您的通用参数应具有可比性的类型.

例如,可以在itselft上进行比较

公共类对< T1扩展Comparable< T1>,T2扩展Comparable< T2>>

这个描述说:

I am a Pair class that works with two parameters, that each of them can be compared with itself.

这就是你可能正在寻找的东西,另外它们可以在一些可以超级T1或T2的东西上进行比较

公共类对< T1扩展Comparable<?超级T1>,T2扩展可比较<?超级T2>

这个描述说:

I am a Pair class that works with two parameters, that each of them can be compared with classes that deliver from them.

我希望这可以帮助你使用泛型;-).

转载注明原文:Java中的可比较和比较器接口 - 代码日志