简体   繁体   English

如何在Java中实现通用的`max(Comparable a,Comparable b)`函数?

[英]How to implement a generic `max(Comparable a, Comparable b)` function in Java?

I'm trying to write a generic max function that takes two Comparable s. 我正在尝试编写一个带有两个Comparable s的泛型max函数。

So far I have 到目前为止我有

public static <T extends Comparable<?>> T max(T a, T b) {
    if (a == null) {
        if (b == null) return a;
        else return b;
    }
    if (b == null)
        return a;
    return a.compareTo(b) > 0 ? a : b;
}

This fails to compiles with 这无法编译

The method compareTo(capture#5-of ?) in the type Comparable<capture#5-of ?> is not applicable for the arguments (T)

What I think this is saying is that that the ? 我认为这说的是那个? in Comparable<?> may be interpreted as one type for parameter a, and another for parameter b, so that they can't be compared. in Comparable<?>可以解释为参数a的一种类型,而参数b的另一种类型,因此无法比较它们。

How do I dig myself out of this hole? 我如何从这个洞中挖掘自己?

For best results you should use public static <T extends Comparable<? super T>> T max(T a, T b) 为了获得最佳效果,您应该使用public static <T extends Comparable<? super T>> T max(T a, T b) public static <T extends Comparable<? super T>> T max(T a, T b) . public static <T extends Comparable<? super T>> T max(T a, T b)

The problem with <T extends Comparable<?>> is that this says that the type T is comparable to some type, but you don't know what that type is. <T extends Comparable<?>>在于,这表示类型T与某种类型相当,但您不知道该类型是什么。 Of course, common sense would dictate that a class which implements Comparable should be able to be comparable to at least itself (ie be able to compare to objects of its own type), but there is technically nothing preventing class A from implementing Comparable<B> , where A and B have nothing to do with each other. 当然,常识会要求实现Comparable的类应该能够至少与其自身相比(即能够与其自身类型的对象进行比较),但从技术上讲,没有什么能阻止A类实现Comparable<B> ,其中A和B彼此无关。 <T extends Comparable<T>> solves this problem. <T extends Comparable<T>>解决了这个问题。

But there's a subtle problem with that. 但是这有一个微妙的问题。 Suppose class X implements Comparable<X> , and I have a class Y that extends X. So class Y automatically implements Comparable<X> by inheritance. 假设类X实现了Comparable<X> ,并且我有一个扩展X的类Y.所以类Y通过继承自动实现Comparable<X> Class Y can't also implement Comparable<Y> because a class cannot implement an interface twice with different type parameters. Y类也不能实现Comparable<Y>因为类不能使用不同的类型参数实现两次接口。 This is not really a problem, since instances of Y are instances of X, so Y is comparable to all instances of Y. But the problem is that you cannot use the type Y with your <T extends Comparable<T>> T max(T a, T b) function, because Y doesn't implement Comparable<Y> . 这不是一个真正的问题,因为Y的实例是X的实例,所以Y与Y的所有实例相当。但问题是你不能使用类型Y和你的<T extends Comparable<T>> T max(T a, T b)函数,因为Y没有实现Comparable<Y> The bounds are too strict. 界限太严格了。 <T extends Comparable<? super T>> <T extends Comparable<? super T>> fixes the problem, because it is sufficient for T to be comparable to some supertype of T (which would include all T instances). <T extends Comparable<? super T>>解决了这个问题,因为T足以与某些超类型的T(包括所有T实例)相比较。 Recall the rule PECS - producer extends , consumer super - in this case, Comparable is a consumer (it takes in an object to compare against), so super makes sense. 回想一下规则PECS - 生产者extends ,消费者super - 在这种情况下, Comparable是一个消费者(它需要一个对象进行比较),所以super是有道理的。

This is the type bounds used by all of the sorting and ordering functions in the Java library. 这是Java库中所有排序和排序函数使用的类型边界。

You get this error because Comparable<?> basically says that it is comparable to something without any specifics. 你得到这个错误,因为Comparable<?>基本上说它与没有任何细节的东西相当。 You should write Comparable<T> instead, so the compiler would know that type T is comparable to itself. 您应该编写Comparable<T> ,因此编译器会知道类型T Comparable<T>自身相当。

Answering my own question from SO's generated related links - this seems to be a subtle duplicate of Fun with Java generics , although I guess you can't blame me for not finding it given the title! 从SO生成的相关链接回答我自己的问题 - 这似乎是Fun with Java泛型的一个微妙的重复,虽然我想你不能责怪我没有找到它的标题!

The simplest solution seems to be 最简单的解决方案似乎是

public static <T extends Comparable<T>> T max(T a, T b) {
    if (a == null) {
        if (b == null) return a;
        else return b;
    }
    if (b == null)
        return a;
    return a.compareTo(b) > 0 ? a : b;
}

I've written a utility class for this. 我为此编写了一个实用程序类。 Maybe you find it useful (the library is Open Source): 也许你觉得它很有用(这个库是开源的):

http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Comparables.html http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Comparables.html

Homepage: 主页:

http://www.softsmithy.org http://www.softsmithy.org

Download: 下载:

http://sourceforge.net/projects/softsmithy/files/softsmithy/ http://sourceforge.net/projects/softsmithy/files/softsmithy/

Maven: Maven的:

<dependency>  
    <groupid>org.softsmithy.lib</groupid>  
    <artifactid>lib-core</artifactid>  
    <version>0.1</version>  
</dependency> 

It's offten better getting already implemented iso create owns. 获得已经实现的iso create owns是最好的。 See at Min / Max function with two Comparable . 使用两个Comparable查看最小/最大功能 Simplest is org.apache.commons.lang.ObjectUtils : 最简单的是org.apache.commons.lang.ObjectUtils

Comparable<C> a = ...;
Comparable<C> b = ...;
Comparable<C> min = ObjectUtils.min(a, b);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM