Java中的比较和比较器接口 [英] Comparable and Comparator Interface in Java

查看:127
本文介绍了Java中的比较和比较器接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

但JDK 1.6编译器会产生警告:

  Comparable是一个原始类型。对泛型类型的引用可比< T>应该参数化

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

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

现在一切顺利,直到我尝试生成一个Comparator for Pair(以下代码是Pair class)

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

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

 方法compareTo(capture#1-of?extends对象)类型为Comparable< capture#1-of?扩展对象>不适用于参数(T1)

任何人都知道这个错误信息是什么意思?
欢迎提供关于此主题的任何提示。


更新:

以下是完整代码:

  public class Pair< T1 extends Comparable <? extends Object>,T2扩展Comparable< ;?扩展对象>> {
私人T1钥匙;
私人T2值;

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

@MarvinLabs你能解释一下为什么编译器不能确定对象是什么与其他相同类型的对象相比较。在上面的代码中, second.getKey()返回T1类型,它与 first.getKey()

  public interface Comparable< T> {

public int compareTo(T o);

}

这是非常典型的,我们必须说。所以如果我们的班级需要实施它,我们会这样做。

  pubilc class ICanComparteWithMyself执行Comparable< ICanComparteWithMyself> {

public int compareTo(ICanComparteWithMyselfo)
//编译代码
}

在我们看到泛型参数类型时,确定我们将要操作的是什么,所以对于泛型我们采用相同的方式。

  public class ICanCompareMyGeneric< T>实现可比< T> {

public int compareTo(T o)
//编译代码
}
}

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

  public class MyGenericCanCompareToItself< T extends Comparable< T>> {b 
$ b}

正如我们所看到的,这是非常常见的使用。预期的限制(或不)是我们可以在自我类型实现Comparable的类上工作。如果我们有

  public class ICanCompareStrings implements Comparable< String> {
public int compareTo(String o)
//编码代码
}
}






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



编辑

因此,当我们介绍基本知识时,我们可以去解决您的问题

您的课程描述如下所示:
$ b $ p $ public class Pair< / p> T1延伸Comparable< ;? extends Object>,T2扩展Comparable< ;?扩展对象>>



这并没有多少感觉,因为它与<?> ;



这段描述说:


I是一个Pair类,它有两个通用参数,可以使用我不知道的东西进行比较。


使用此代码你不能在通用参数不知道的情况下继续前进,然后在那里操作,最终得到类似的结果。

first.getKey.compareTo(null);



这就是为什么你的代码在你试图进行强制转换时不能编译,所需的类型为空。






为了改变这种情况,您需要确定您的通用参数应该具有可比性的类型。 b

例如,can可以比较它自己

public class Pair< T1 extends Comparable< T1>,T2 extends Comparable< ; T2>>< / code>< / p>

< p>这段描述是:


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


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



公共类对< T1扩展可比较< ;?超级T1>,T2延伸可比<?超级T2>>< / code>< / p>

< p>这个描述是:

lockquote




我是一个Pair类,它有两个参数,它们可以与它们交付的类进行比较。 >我希望这可以帮助你与泛型; - )。


I want to write a generic Pair class, which has two members: key and value. The only requirement to this class is that both key and value should implements the Comparable interface, otherwise Pair class will not accept them as type parameter.
First I code it like this:

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

But the JDK 1.6 compiler will generate warning about this:

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

Then I tried to add type parameters and the code now looks like this:

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

Now everything go well until I tried to generate an Comparator for Pair.(The following code is in Pair class)

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

The code first.getKey().compareTo(second.getKey()); will generate an error saying:

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

Anyone knows what does this error message mean?
Any hints on this topic are welcome.

UPDATE:
Here is the complete code:

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 Can you explain a bit more why the compiler cannot make sure objects are compared to other objects of the same type. In the above code, second.getKey() returns T1 type, which is of the same type as first.getKey()

解决方案

Lets get a look at interface design first.

public interface Comparable<T> { 

   public int compareTo(T o);

} 

It is quite typical we must say. So if our class needs to implement it we do this.

pubilc class ICanComparteWithMyself implements Comparable<ICanComparteWithMyself> { 

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

As we see the generic parameter type, determine on what we will operate, so for generics we act in the same way

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

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

In your case whawt we want it to assure that generic parameters implements is own Comparable, for that we need to do this

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

}

As we can see, this is quite common to use. The limitation expected (or not) is that we can work on classes that implement Comparable for it self type. If we had

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


So for class MyGenericCanCompareToItself as generic parameter we can use class public MyGenericCanCompareToItself but not ICanCompareStrings.

EDIT:

So when we covered the basics now we can go to solve, your problem

Your class description looks like this

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

This do not have much sensce as is more less the same as <?>

This description says:

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

With this code you cann not progress before the generic parameters do not know on that then operate there for you end up with something like this.

first.getKey.compareTo(null);

And this why you code do not compile when you try to cast, the expected type is null.


To change that you need to qualify on what type your generic parameters should be comparable.

For example the can compare on itselft

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

This descriptions says:

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

And this is what you probably are looking for, additionally they can be compared on something that can be super class of T1 or T2

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

This description says:

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

I hope this helps you out with generics ;-).

这篇关于Java中的比较和比较器接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆