Java 为什么我的比较方法违反了它的总合同?
另外,time对象是来自Joda时间库的DateTime实例,TransportType是包含常量Train、Seaship、Barge和Truck的枚举 编辑: 好的,我将比较器编辑为:Java 为什么我的比较方法违反了它的总合同?,java,comparator,Java,Comparator,另外,time对象是来自Joda时间库的DateTime实例,TransportType是包含常量Train、Seaship、Barge和Truck的枚举 编辑: 好的,我将比较器编辑为: public DateTime time; public int maxDuration; public TransportType transportType; public String transportCompany; 总合同是这样的 @Override
public DateTime time;
public int maxDuration;
public TransportType transportType;
public String transportCompany;
总合同是这样的
@Override
public int compareTo(LocationMovement lm) {
if (this.time.isBefore(lm.time))
return -1;
else if (this.time.isAfter(lm.time))
return +1;
else {
int c = this.maxDuration - lm.maxDuration;
if (c != 0) return c;
c = this.transportCompany.compareTo(lm.transportCompany);
if (c != 0) return c;
c = this.transportType.ordinal() - lm.transportType.ordinal();
return c;
}
}
在您的情况下,一种方式返回-1的代码可能会另一种方式返回0。请注意,如果两个容器
c1
和c2
具有相同的离开时间,但其他属性不同,则比较(c1,c2)
和比较(c2,c1)
将返回+1
,即。,c1>c2
和c2>c1
相反,您应该完全删除其他字段,或者在出发时间相等的情况下,在嵌套或顺序if else
s中分别比较它们
看看这个,可以找到一种通过多个属性比较对象的干净方法。为了实现比较
,您检查的所有事物必须具有彼此“较小”、“较大”或“相等”的概念,然后您必须决定检查它们的顺序,返回第一个不相等项的较小值/较大值。这样,您就满足了compare(a,b)
必须与compare(b,a)
相反的契约。如果您正在比较的所有部分都没有“大”或“小”的概念(例如,传输类型),那么要么您无法实现比较
,要么您必须强制对它们进行任意(但可靠)的大/小解释
下面是一个这样做的概念性示例。在本例中,我(任意)选择的顺序是:时间、持续时间、公司和类型。但不同的顺序可能更合理。这只是一个例子。另外,您还没有说明transportType
的类型,因此我假设它有一个compareTo
方法;显然,它可能不是,你可能不得不调整
COMPARATOR.compare(a, b) = - COMPARATOR.compare(b, a)
公共静态比较器离开=新比较器(){
@凌驾
公共int比较(容器container1、容器container2){
int-rv;
//时代
rv=集装箱1.出发时间.比较(集装箱2.出发时间);
如果(rv==0){
//持续时间
if(container1.deafit.maxDurationcontainer2.deposition.maxDuration){
rv=1;
}
否则{
//运输公司
rv=集装箱1.出发.运输公司.比较(集装箱2.出发.运输公司);
如果(rv==0){
//运输类型
rv=集装箱1.出发.运输类型.比较(集装箱2.出发.运输类型);
}
}
}
返回rv;
}
};
如果集装箱c1
和集装箱c2
具有相同的出发时间
,但其他属性不同,则两者都比较(c1,c2)
和比较(c2,c1)
将返回+1
。旁注:在中进行如此巨大的计算,否则如果只是自找麻烦。谢谢你们的回答。你能看一下我的编辑吗?你的前两个if
检查相同的条件。此外,在“equals”(新的else
)情况下,您还应该有可能返回-1
,或者您仍然存在与第一种方法相同的问题。在您的解决方案中,如果(c!=0)返回c,您当然可以更改最后一个;返回0
to返回c代码>。(您可以只返回顺序比较的结果,但如果您先将其放入c
,则更容易调试。)我可以看到他的原始代码如何在一个方向返回1
,而在另一个方向返回0
,但无法看到它如何返回-1
和0
。当然,没关系,问题是一样的。谢谢你的回答,我已经编辑了我的问题,其中包含了我的解决方案。
public static Comparator<Container> ARRIVAL = new Comparator<Container>() {
@Override
public int compare(Container container1, Container container2) {
return container1.arrival.compareTo(container2.arrival);
}
};
public static Comparator<Container> DEPARTURE = new Comparator<Container>() {
@Override
public int compare(Container container1, Container container2) {
return container1.departure.compareTo(container2.departure);
}
};
@Override
public int compareTo(LocationMovement lm) {
if (this.time.isBefore(lm.time))
return -1;
else if (this.time.isAfter(lm.time))
return +1;
else {
int c = this.maxDuration - lm.maxDuration;
if (c != 0) return c;
c = this.transportCompany.compareTo(lm.transportCompany);
if (c != 0) return c;
c = this.transportType.ordinal() - lm.transportType.ordinal();
return c;
}
}
COMPARATOR.compare(a, b) = - COMPARATOR.compare(b, a)
public static Comparator<Container> DEPARTURE = new Comparator<Container>() {
@Override
public int compare(Container container1, Container container2) {
int rv;
// Times
rv = container1.departure.time.compareTo(container2.departure.time);
if (rv == 0) {
// Duration
if (container1.departure.maxDuration < container2.departure.maxDuration) {
rv = -1;
}
else if (container1.departure.maxDuration > container2.departure.maxDuration) {
rv = 1;
}
else {
// Transport company
rv = container1.departure.transportCompany.compareTo(container2.departure.transportCompany);
if (rv == 0) {
// Transport type
rv = container1.departure.transportType.compareTo(container2.departure.transportType);
}
}
}
return rv;
}
};