比较者一般合同违规

Ôre*_*rel 1 java sorting collections

我已阅读有关传递比较器的所有线程,我不明白为什么这个比较器函数违反了规则.如果有人可以清洁我的眼睛,我认为这很简单,但我无法得到它

堆栈是:

java.util.TimSort.mergeLo(TimSort.java:747)
java.util.TimSort.mergeAt(TimSort.java:483)
java.util.TimSort.mergeCollapse(TimSort.java:410)
Run Code Online (Sandbox Code Playgroud)

我的对象(简化)

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

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

比较器静态分为一类

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;
            }
        }
    };
Run Code Online (Sandbox Code Playgroud)

主要是我希望按日期对事件进行排序,如果两个事件具有相同的日期时间,则将begin事件设置为first,将end事件设置为last.

我没有触发错误的集合

Era*_*ran 5

如果比较两个SleepDetails具有相同的实例getTime(),其中一个具有getType()BEGIN,另一个具有AWAKE.

compare (one, two)
Run Code Online (Sandbox Code Playgroud)

会给-1

compare (two, one)
Run Code Online (Sandbox Code Playgroud)

会给0

这违反了合同:

实现者必须确保所有x和y的sgn(compare(x,y))== -sgn(compare(y,x)).

您还必须检查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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)