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

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

到目前为止我有

 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 is not applicable for the arguments (T) 

我认为这是说的那个? in Comparable可以解释为参数a的一种类型,而参数b的另一种类型,因此无法比较它们。

我如何从这个洞中挖掘自己?

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

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

但是这有一个微妙的问题。 假设类X实现了Comparable ,并且我有一个扩展X的类Y.所以类Y通过inheritance自动实现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库中所有排序和排序函数使用的类型边界。

你得到这个错误,因为Comparable基本上说它可以与没有任何细节的东西相比。 您应该编写Comparable ,因此编译器会知道类型T Comparable自身相当。

从SO生成的相关链接回答我自己的问题 – 这似乎是Fun with Javagenerics的一个微妙的重复,虽然我想你不能责怪我没有找到它的标题!

最简单的解决方案似乎是

 public static > 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://www.softsmithy.org

下载:

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

Maven的:

  org.softsmithy.lib lib-core 0.1