是否有理由为其他类型的类型实现java.util.Comparable?

时间:2017-01-20 09:04:04

标签: java

实现Comparable<T>的类通常会为自己实现它,例如

class MyInteger implements Comparable<MyInteger> { ... }
class MyString implements Comparable<MyString> { ... }

但没有什么可以阻止你为不同的类型实现它:

class MyString implements Comparable<MyInteger> { ... }

可让您将MyStringMyInteger进行比较。

正如所描述的enter image description hereComparable旨在模拟自然排序,即in the Javadoc,因此能够具有反对称性,参数的类型compareTo的{​​{1}}应该与定义该方法的类型相同。

但实施class SomeType implements Comparable<OtherType>是否有任何实际用途(滥用)?

更新total orderJoni提供的答案给出了隐式实现Comparable<Supertype>的实际示例,即您的类在哪里可传递地实现该接口。知道是否有人可以使用显式的例子会很有趣。

2 个答案:

答案 0 :(得分:4)

如果有父/子关系,你会发现这一点。例如,Enum类实现Comparable<E>,其中E是类型参数。所有枚举共享这个compareTo实现。

澄清:Enum<ConcreteClass>实施Comparable<ConcreteClass>。如果它遵循模式,您希望它实现Comparable<Enum<ConcreteClass>>

答案 1 :(得分:4)

您遇到此问题的明显(事后看来)情况是在实现Comparable的类的子类中:

abstract class Superclass implements Comparable<Superclass> {}
abstract class Subclass extends Superclass {}

System.out.println(Subclass.class.getGenericInterfaces()[0]);
// Prints Comparable<Superclass>

与以往一样,Bloch的 Effective Java 2nd Ed 在第8项“考虑实施可比较”中有很好的见解:

  

compareTo合同中这三条规定的一个后果是由...强制进行的等式测试   compareTo方法必须遵守equals合同施加的相同限制:   反身性,对称性和传递性。因此,同样的警告适用:   没有办法使用新的值组件扩展可实例化的类   保留compareTo合同,除非你愿意放弃   面向对象的抽象(第8项)。

所以,这说明如果您的子类没有比用于确定排序的超类更多的值,那么实现Comparable<Supertype>是合理的。

除了Comparable的一般要求之外,其含义是Comparable<Superclass>应该在Superclass和所有子类中以相同的方式实现。

如果compareTo是一个类,则表明final应标记为Superclass。如果它是一个接口,您可以在Java 8+中提供默认实现;但是没有(内置)方法来强制执行该方法在实现类时不会被重写。