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

发布于 2024-11-17 07:30:59 字数 617 浏览 1 评论 0 原文

我正在尝试编写一个需要两个 Comparable 的通用 max 函数。

到目前为止,我的

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 无法编译

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

我认为这说明的是 Comparable 中的 ? 可以被解释为参数 a 的一种类型,另一个参数b,这样它们就不能进行比较。

我怎样才能把自己从这个坑里挖出来呢?

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

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.

How do I dig myself out of this hole?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

放低过去 2024-11-24 07:30:59

为了获得最佳结果,您应该使用 public static > T max(T a, T b)。

> 的问题是,这表示类型 T 可以与某种类型进行比较,但您不知道该类型是什么。当然,常识表明,实现 Comparable 的类应该至少能够与自身进行比较(即能够与自己类型的对象进行比较),但从技术上讲,没有什么可以阻止类 A 实现 可比较,其中A和B彼此无关。 > 解决了这个问题。

但这有一个微妙的问题。假设类 X 实现了 Comparable,并且我有一个扩展 X 的类 Y。因此类 Y 通过继承自动实现了 Comparable。类 Y 也无法实现 Comparable,因为一个类无法使用不同的类型参数两次实现一个接口。这并不是真正的问题,因为 Y 的实例是 X 的实例,因此 Y 可以与 Y 的所有实例进行比较。但问题是您不能将类型 Y 与 一起使用。 > T max(T a, T b) 函数,因为 Y 未实现 Comparable。界限太严格了。 > 解决了这个问题,因为 T 足以与 T 的某些超类型(包括所有 T 实例)进行比较。回想一下 PECS 规则 - 生产者 extends,消费者 super - 在这种情况下,Comparable 是一个消费者(它接受一个对象进行比较) ,所以 super 是有道理的。

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

For best results you should use 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.

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, Comparable is a consumer (it takes in an object to compare against), so super makes sense.

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

十二 2024-11-24 07:30:59

您收到此错误是因为 Comparable 基本上表示它可以与没有任何细节的东西进行比较。您应该改为编写 Comparable,这样编译器就会知道类型 T 可以与其自身进行比较。

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.

ι不睡觉的鱼゛ 2024-11-24 07:30:59

从SO生成的相关链接回答我自己的问题 - 这似乎是 Fun with Java generics 的微妙重复,尽管我猜你不能怪我没有找到它的标题!

最简单的解决方案似乎是

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

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!

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;
}
紫﹏色ふ单纯 2024-11-24 07:30:59

我为此编写了一个实用程序类。也许您发现它很有用(该库是开源的):

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

主页:

http://www.softsmithy.org

下载:

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

Maven:

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

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

Homepage:

http://www.softsmithy.org

Download:

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

Maven:

<dependency>  
    <groupid>org.softsmithy.lib</groupid>  
    <artifactid>lib-core</artifactid>  
    <version>0.1</version>  
</dependency> 
当梦初醒 2024-11-24 07:30:59

最好已经实现 iso create owns。请参阅具有两个 Comparable 的最小/最大函数。最简单的是org.apache.commons.lang.ObjectUtils:

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

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:

Comparable<C> a = ...;
Comparable<C> b = ...;
Comparable<C> min = ObjectUtils.min(a, b);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文