2016-12-07 69 views
1

我已经读过关于传递比较器的所有线程,我不明白为什么这个比较函数违反规则。如果有人可以清理自己的眼睛,这是很简单的,我认为,但我不能让它比较一般合同违规

堆栈是:(简体)

java.util.TimSort.mergeLo(TimSort.java:747) 
java.util.TimSort.mergeAt(TimSort.java:483) 
java.util.TimSort.mergeCollapse(TimSort.java:410) 

我的对象

public class SleepDetails { 
    private DateTime time; 
    private SleepEnum type; 
    [...] 
} 

public enum SleepEnum { 
    DEEP(0), LIGHT(1), AWAKE(2), BEGIN(16), END(17); 
    [...] 
} 

比较静态成类

Comparator<SleepDetails> comparator = new Comparator<SleepDetails>(){ 
     public int compare(SleepDetails arg0, SleepDetails arg1) { 
      int res = arg0.getTime().compareTo(arg1.getTime()); 
      if (res != 0) 
       return res; 
      if (arg0.getType() == arg1.getType()) 
       return 0; 
      switch(arg0.getType()) { 
       case BEGIN: 
       return -1; 
       case END: 
       return 1; 
       default: 
       return 0; 
      } 
     } 
    }; 

主要我想按日期排序事件,如果两个事件具有相同的日期时间作为最后的开始事件和结束事件。

我没有收集触发的bug

+0

'switch(arg0.getType())' - 你没有比较。 –

+0

呃@Bene什么?类似的方法绝对不会遵循这一点。 'Integer.compare(1,2)!= Integer.compare(2,1)'。实际上,它们只是相匹配。 – Rogue

+0

我的坏,不同的故事 – Bene

回答

5

如果你比较具有相同getTime() 2个SleepDetails实例,其中一人有getType() BEGIN和其他醒来。

compare (one, two) 

会给-1

​​

会给0

这违反了合同:

实现程序必须确保SGN(比较( x,y))== -sgn(比较(y,x))和y。

您还必须检查arg1.getType()compare方法(当arg0.getType()既不BEGIN也不END)。

public int compare(SleepDetails arg0, SleepDetails arg1) { 
     int res = arg0.getTime().compareTo(arg1.getTime()); 
     if (res != 0) 
      return res; 
     if (arg0.getType() == arg1.getType()) 
      return 0; 
     switch(arg0.getType()) { 
      case BEGIN: 
      return -1; 
      case END: 
      return 1; 
      default: 
      switch(arg1.getType()) { 
       case BEGIN: 
       return 1; 
       case END: 
       return -1; 
       default: 
       return 0; 
      } 
     } 
    } 
+0

好的,谢谢晶莹剔透 –

1

问题是您的代码不区分BEGIN和END以外类型的枚举值。特别是,当第一个类型既不是BEGIN也不是END时,它将返回零,而不管第二种类型。

但是,这种行为是不对称的:如果你交换一对BEGIN和LIGHT中的两个项目,你会得到-1和0,打破了对称性。

您可以将除BEGIN和END之外的所有其他类型视为彼此相等,但在决定相等性时您需要使用双方。

相关问题