Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的可比和比较器接口_Java_Generics_Comparator_Comparable - Fatal编程技术网

Java中的可比和比较器接口

Java中的可比和比较器接口,java,generics,comparator,comparable,Java,Generics,Comparator,Comparable,我想编写一个泛型Pair类,它有两个成员:key和value。这个类的唯一要求是key和value都应该实现可比较的接口,否则Pair类将不接受它们作为类型参数 首先,我将其编码如下: public class Pair<T1 extends Comparable, T2 extends Comparable> public class Pair<T1 extends Comparable<? extends Object>,

我想编写一个泛型Pair类,它有两个成员:key和value。这个类的唯一要求是key和value都应该实现可比较的接口,否则Pair类将不接受它们作为类型参数
首先,我将其编码如下:

public class Pair<T1 extends Comparable, T2 extends Comparable>
public class Pair<T1 extends Comparable<? extends Object>,
                  T2 extends Comparable<? extends Object>>
有人知道这个错误消息是什么意思吗
欢迎对此主题提供任何提示

更新:
以下是完整的代码:

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

公共类对我将声明我的类如下:

public class Pair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> 
公共类对
这意味着对象可以与相同类型的对象进行比较(您的错误意味着编译器无法确保对象与相同类型的其他对象进行比较)


您的“我的编辑”代码可以正确编译:

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

    public T1 getKey() {
        return key;
    }

    public T2 getValue() {
        return value;
    }

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

    public static void test() {
        Pair<String, Integer> p1 = new Pair<String, Integer>();
        Pair<String, Integer> p2 = new Pair<String, Integer>();

        p1.KEY_COMPARATOR.compare(p1, p2);
    }
}
公共类对{
私钥;
私人T2值;
公共T1 getKey(){
返回键;
}
公共值(){
返回值;
}
公共最终比较器键\u比较器=新比较器(){
公共整数比较(第一对,第二对){
返回first.getKey().compareTo(second.getKey());
}
};
公共静态无效测试(){
对p1=新对();
配对p2=新配对();
p1.键比较器。比较(p1,p2);
}
}

但是,您应该为比较器创建一个单独的类(或静态最终类),这样使用起来更直观,而且不会增加每对实例的权重。

让我们先看看接口设计

public interface Comparable<T> { 

   public int compareTo(T o);

} 
公共接口{
公共国际比较(TO);
} 
我们必须说,这是相当典型的。因此,如果我们的类需要实现它,我们就这样做

pubilc class ICanComparteWithMyself implements Comparable<ICanComparteWithMyself> { 

public int compareTo(ICanComparteWithMyselfo)    
   //code for compration
} 
publilc类ICANComparateWithIf实现了可比较的{
public int compareTo(我与自己比较)
//压缩编码
} 
当我们看到泛型参数类型时,确定我们将操作什么,因此对于泛型,我们以相同的方式操作

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

   public int compareTo(T o)    
       //code for compration
    } 
}
public类ICANComareMygeneric实现可比较{
公共内部比较(TO)
//压缩编码
} 
}
在您的情况下,我们希望它确保泛型参数实现是可比的,为此我们需要这样做

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

}
公共类MyGenericCanComparetSelf{
}
正如我们所看到的,这是非常常见的使用。预期(或不预期)的限制是,我们可以在实现可比的for it self类型的类上工作。如果我们有

 public class ICanCompareStrings implements Comparable<String> {
      public int compareTo(String o)    
           //code for compration
      }
 }
public类ICANComarestrings实现可比较{
公共整数比较(字符串o)
//压缩编码
}
}

因此,对于class
MyGenericCanCompareTeslf
作为泛型参数,我们可以使用class
public MyGenericCanCompareTeslf
,但不能使用
ICANComareTestrings

编辑:

所以当我们学习了基本知识之后,我们可以开始解决你的问题了

您的类描述如下所示

公共类对

这个描述说:

我是一个Pair类,它使用两个泛型参数,可以对我不知道的东西进行比较

有了这段代码,你就无法在通用参数不知道的情况下继续前进,然后在那里进行操作,最终得到类似这样的结果

first.getKey.compareTo(null)

这就是为什么当您尝试强制转换时,代码不编译,预期的类型为null


要改变这一点,您需要限定泛型参数应具有可比性的类型

例如,可以在其自身上进行比较

公共类对

这说明说:

我是一个Pair类,它使用两个参数,每个参数都可以与自身进行比较

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


公共类对如果您知道以下各项之间的差异:

List<Object>
列表

列表
。。。这会更容易。基本上,它们在java中是两种不同的类型(不像您认为的“相同”列表类型)

一般类型的“逻辑”并不像你想象的那样或看起来的那样简单

我认为您应该声明您的“结对”类如下:

public class Pair<T1 extends Comparable<T1>, T2 extends Comparable<T2>>
公共类对
既然已经使“T1”和“T2”具有可比性,为什么要实现比较器呢

如果您想使用“Collections.sort(myCollection,myComparator)”,那么您不必声明“T1”和“T2”是“可比较的”…只需确保您的“KEY\u COMPARATOR”接受它们


无论哪种方式,代码中都存在冗余。

是的,这解决了问题,非常感谢。在我提供的代码中,即使添加类型转换,错误消息仍然存在:first.getKey().compareTo((T1)(second.getKey()))。类型转换应该通知编译器另一个对象的类型相同。为什么它仍然给出错误消息?同样,我想您需要声明T1和T2是可比较的。因此:
new Comparator
I更新了我的问题,请参阅完整的代码(不长)详细信息。你能再解释一下为什么编译器不能确保对象与相同类型的其他对象进行比较吗?@MarvinLabs,这里不需要强制转换。@cheng:使用
T1 extends Comparable是没有意义的。如果你仍然有问题,请使用我的编辑。如果没有,请接受帮助你解决问题的答案。
 public class ICanCompareStrings implements Comparable<String> {
      public int compareTo(String o)    
           //code for compration
      }
 }
List<Object>
List<String>
public class Pair<T1 extends Comparable<T1>, T2 extends Comparable<T2>>