在Comparable的合同中,没有任何东西强迫对象与自身相比。这只是
强烈推荐,但并非严格要求(x.compareTo(y)== 0)==(x.equals(y))
这意味着推荐 x.compareTo(x)
不要抛出。但是可以写一个
class X implements Comparable<Y> {
...
}
其中X
和Y
是两个不相关的类。我看不出它有什么好处,但是在{8}的Java 8版本中,甚至还有相应的检查。
X implements Comparable<Y>
吗?我猜答案是肯定的,不是,但这只是猜测
答案 0 :(得分:4)
Comparable
宣传合同,其中比较应与equals保持一致,即(a.compareTo(b) == 0) == a.equals(b)
。但它并没有强迫你这样做,任何奇怪的合同都可以强制执行。
所以你可以创建一个:
class DumbInteger implements Comparable<DumbInteger> {
private final int i;
public DumbInteger(int i) { this.i = i; }
public int compareTo(DumbInteger di) { return 0; }
public boolean equals(Object other) { /* checks */ return other.i == this.i; }
}
你也可以创建一个:
class DumberInteger implements Comparable<String> {
private final int i;
public DumberInteger(int i) { this.i = i; }
public int compareTo(String s) { return 0; }
public boolean equals(Object other) { /* checks */ return other.i == this.i; }
public static void main(String[] args) {
System.out.println(new DumberInteger(0).compareTo("abc"));
}
}
但这样做可能没有意义。在任何情况下,这都不是特定于Java 8的,因为Comparable接口自Java 2以来一直存在并且在Java 5中“泛化”。
但它可能不是Comparable接口本身的一个缺陷,因为我认为在Java中没有办法创建一个只能通过类实现的通用接口I<T>
。属于T
的子类型。
答案 1 :(得分:1)
我看到我错过了合同的一部分,也没有看到HashMap.comparableClassFor
存在的原因。
合同说明
(x.compareTo(y)&gt; 0&amp; y.compareTo(z)&gt; 0)表示x.compareTo(z)&gt; 0
因此只要X
大于Y
且Y
大于X
,那么X
的两个实例必须与彼此。这并没有留下太多的自由:
X
的所有实例都小于或等于Y
的所有实例(或相反的方向)。这略微不那么荒谬。所以,我总结说这是可能的,但没有任何意义。最简单的例子是
class X implements Comparable<Void> {
public int compareTo(Void v) {
return 43; // or throw or whatever, it doesn't matter
}
}
我想HashMap.comparableClassFor
的原因是支持公共超类的不同实现,如
abstract class AByteArray implements Comparable<AByteArray> {}
class SparseByteArray extends AByteArray {...}
class DenseByteArray extends AByteArray {...}
这似乎有道理,甚至可以与平等一致。
答案 2 :(得分:0)
将两个类Comparable
相互关联的一个问题是因为它将这些类紧密地结合在一起。这使得在另一种情况下难以重用该类。
这是完整的代码 https://gist.github.com/cevaris/11099129
X x = new X();
x.xTest = 10;
Y y = new Y();
y.yTest = 100;
System.out.println("x.compareTo(y) == -1: " + (x.compareTo(y) == -1)); //True
System.out.println("y.compareTo(x) == 1: " + (y.compareTo(x) == 1)); //True
这是Y实现。
class Y implements Comparable<X> {
int yTest;
@Override
public int compareTo(X o) {
if(this.yTest < o.xTest) return -1;
if(this.yTest > o.xTest) return 1;
return 0;
}
}
这是X实现。
class X implements Comparable<Y> {
int xTest;
@Override
public int compareTo(Y o) {
if(this.xTest < o.yTest) return -1;
if(this.xTest > o.yTest) return 1;
return 0;
}
}
答案 3 :(得分:0)
好吧,它在技术上是可以完成的(按照 @cevaris' answer)并且当您有多种表示同一对象的方法时可以理解,例如一个对象及其 String
表示。但是,如果您可以两次实现相同的接口,这才有意义:
public class CompInt implements Comparable<CompInt>, Comparable<String> {
但由于 type erasure,Java 中禁止这样做。