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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6452313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:56:23  来源:igfitidea点击:

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

javagenericscomparable

提问by Duncan McGregor

I'm trying to write a generic max function that takes two Comparables.

我正在尝试编写一个需要两个Comparables的通用 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.

我认为这是说?inComparable<?>可以解释为参数 a 的一种类型,参数 b 的另一种类型,因此无法比较它们。

How do I dig myself out of this hole?

我怎么把自己从这个洞里挖出来?

回答by newacct

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).

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. Of course, common sense would dictate that a class which implements Comparable should be able to be comparable to at least itself (i.e. 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. <T extends Comparable<T>>solves this problem.

问题<T extends Comparable<?>>在于,这表示类型 T 与某种类型相当,但您不知道该类型是什么。当然,常识会要求实现 Comparable 的类至少应该能够与自身进行比较(即能够与自己类型的对象进行比较),但是从技术上讲,没有什么可以阻止类 A 实现Comparable<B>,其中 A和 B 没有任何关系。<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. Class Y can't also implement Comparable<Y>because a class cannot implement an interface twice with different type parameters. 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>. The bounds are too strict. <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). Recall the rule PECS - producer extends, consumer super- in this case, Comparableis a consumer (it takes in an object to compare against), so supermakes sense.

但这有一个微妙的问题。假设类 X 实现了Comparable<X>,我有一个扩展 X 的类 Y。所以类 YComparable<X>通过继承自动实现。YComparable<Y>类也不能实现,因为一个类不能用不同的类型参数两次实现一个接口。这不是一个真正的问题,因为 Y 的实例是 X 的实例,所以 Y 可以与 Y 的所有实例相比较。但问题是你不能在你的<T extends Comparable<T>> T max(T a, T b)函数中使用 Y 类型,因为 Y 没有实现Comparable<Y>。界限太严了。<T extends Comparable<? super T>>解决了这个问题,因为 T 足以与 T 的某个超类型(包括所有 T 实例)进行比较。回想一下规则 PECS——生产者extends、消费者super——在这种情况下,Comparable是一个消费者(它需要一个对象来比较),所以super是有道理的。

This is the type bounds used by all of the sorting and ordering functions in the Java library.

这是 Java 库中所有排序和排序函数使用的类型边界。

回答by Malcolm

You get this error because Comparable<?>basically says that it is comparable to something without any specifics. You should write Comparable<T>instead, so the compiler would know that type T is comparable to itself.

你得到这个错误是因为Comparable<?>基本上说它与没有任何细节的东西相当。您应该Comparable<T>改为编写,这样编译器就会知道类型 T 与其自身相当。

回答by Duncan McGregor

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 generics的微妙重复,尽管我想你不能因为标题而责怪我没有找到它!

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

回答by Puce

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:

马文:

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

回答by Grigory Kislin

It's offten better getting already implemented iso create owns. See at Min / Max function with two Comparable. Simplest is org.apache.commons.lang.ObjectUtils:

通常更好地实现iso create owns。请参见具有两个 Comparable 的 Min/Max 函数。最简单的是org.apache.commons.lang.ObjectUtils

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