[英]How to implement a generic `max(Comparable a, Comparable b)` function in Java?
我正在尝试编写一个带有两个Comparable
s的泛型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;
}
这无法编译
The method compareTo(capture#5-of ?) in the type Comparable<capture#5-of ?> is not applicable for the arguments (T)
我认为这说的是那个?
in Comparable<?>
可以解释为参数a的一种类型,而参数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)
。
<T extends Comparable<?>>
在于,这表示类型T与某种类型相当,但您不知道该类型是什么。 当然,常识会要求实现Comparable的类应该能够至少与其自身相比(即能够与其自身类型的对象进行比较),但从技术上讲,没有什么能阻止A类实现Comparable<B>
,其中A和B彼此无关。 <T extends Comparable<T>>
解决了这个问题。
但是这有一个微妙的问题。 假设类X实现了Comparable<X>
,并且我有一个扩展X的类Y.所以类Y通过继承自动实现Comparable<X>
。 Y类也不能实现Comparable<Y>
因为类不能使用不同的类型参数实现两次接口。 这不是一个真正的问题,因为Y的实例是X的实例,所以Y与Y的所有实例相当。但问题是你不能使用类型Y和你的<T extends Comparable<T>> T max(T a, T b)
函数,因为Y没有实现Comparable<Y>
。 界限太严格了。 <T extends Comparable<? super T>>
<T extends Comparable<? super T>>
解决了这个问题,因为T足以与某些超类型的T(包括所有T实例)相比较。 回想一下规则PECS - 生产者extends
,消费者super
- 在这种情况下, Comparable
是一个消费者(它需要一个对象进行比较),所以super
是有道理的。
这是Java库中所有排序和排序函数使用的类型边界。
你得到这个错误,因为Comparable<?>
基本上说它与没有任何细节的东西相当。 您应该编写Comparable<T>
,因此编译器会知道类型T Comparable<T>
自身相当。
从SO生成的相关链接回答我自己的问题 - 这似乎是Fun with Java泛型的一个微妙的重复,虽然我想你不能责怪我没有找到它的标题!
最简单的解决方案似乎是
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;
}
我为此编写了一个实用程序类。 也许你觉得它很有用(这个库是开源的):
http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Comparables.html
主页:
下载:
http://sourceforge.net/projects/softsmithy/files/softsmithy/
Maven的:
<dependency>
<groupid>org.softsmithy.lib</groupid>
<artifactid>lib-core</artifactid>
<version>0.1</version>
</dependency>
获得已经实现的iso create owns是最好的。 使用两个Comparable查看最小/最大功能 。 最简单的是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.