public static Comparator<Container> DEPARTURE = new Comparator<Container>() {
@Override
public int compare(Container container1, Container container2) {
if (container1.departure.time.isBefore(container2.departure.time))
return -1;
else if (container1.departure.time.equals(container2.departure.time) &&
container1.departure.maxDuration == container2.departure.maxDuration &&
container1.departure.transportCompany.equals(container2.departure.transportCompany) &&
container1.departure.transportType == container2.departure.transportType)
return 0;
else
return +1;
}
};
出发变量只是包含以下字段的对象的实例:
public DateTime time;
public int maxDuration;
public TransportType transportType;
public String transportCompany;
附: time对象是来自Joda-Time库的DateTime实例,TransportType是包含常量Train,Seaship,Barge和Truck的枚举。
编辑:
好的,所以,我把我的比较器编辑成如下:
public static Comparator<Container> DEPARTURE = new Comparator<Container>() {
@Override
public int compare(Container container1, Container container2) {
if (container1.departure.time.isBefore(container2.departure.time))
return -1;
else if (container1.departure.time.isBefore(container2.departure.time))
return +1;
else {
if (container1.departure.maxDuration == container2.departure.maxDuration && container1.departure.transportType == container2.departure.transportType && container1.departure.transportCompany.equals(container2.departure.transportCompany))
return 0;
else
return +1;
}
}
};
但这显然违反了总合同。我如何按时间排序,然后按照其他属性对具有相同时间的对象进行排序,只关注它们是否相等?希望这有道理......
编辑:解决方案
谢谢大家回答我的问题!在研究了你的评论后,我提出了以下似乎有效的解决方案(虽然没有经过彻底的测试):
我实际上把比较部分移到他的班级,因为我还需要通过抵达进行比较。我决定简单地按所有属性排序(连续时间,maxDuration,transportCompany和transportType),我想出的解决方案是:
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);
}
};
然后是compareTo方法:
@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;
}
}
为了实现compare
,你检查的所有东西必须具有彼此“较小”,“更大”或“相等”的概念,然后你必须决定检查它们的顺序,返回较小的/第一个不相等的项目更大。这样,你满足compare(a, b)
必须与compare(b, a)
相反的合同。如果您所比较的所有部分都没有“更大”或“更小”的概念(例如,传输类型),那么要么您不能实施compare
,要么必须强制任意(但可靠) )对它们的更多/更少的解释。
这是一个这样做的概念性例子。在这种情况下,我(任意)选择的顺序是:时间,持续时间,公司和类型。但是不同的顺序可能更合理。这只是一个例子。另外,你还没有说过什么类型的transportType
,所以我认为它有一个compareTo
方法;显然它可能没有,你可能需要调整它。
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;
}
};
总合同是那样的
COMPARATOR.compare(a, b) = - COMPARATOR.compare(b, a)
在您的情况下,以一种方式返回-1的代码可以返回0另一种方式。
请注意,如果两个容器c1
和c2
具有相等的departure.time
,但其他属性不同,那么compare(c1, c2)
和compare(c2, c1)
将返回+1
,即c1>c2
和c2>c1
。
相反,您应该完全删除其他字段,或者在嵌套或顺序if-else
s中单独比较它们,以防出发时间相等。
看看这个answer to a related question,以便通过多个属性比较对象。