"相同排序"对象相等的重要性是什么?

Jer*_*emy 2 java sorting comparator

我正在排序一个对象数组.对象有很多字段,但我只关心其中一个.所以,我写了一个比较器:

    Collections.sort(details, new Comparator<MyObj>() {
        @Override
        public int compare(MyObj d1, MyObj d2) {
            if (d1.getDate() == null && d2.getDate() == null) {
                return 0;
            } else if (d1.getDate() == null) {
                return -1;
            } else if (d2.getDate() == null) {
                return 1;
            }

            if (d1.getDate().before(d2.getDate())) return 1;
            else if (d1.getDate().after(d2.getDate())) return -1;
            else return 0;
        }
    });
Run Code Online (Sandbox Code Playgroud)

从我的用例的角度来看Comparator,即使我认为这种排序是非确定性的,它也能满足它的需要.但是,我想知道这是不好的代码.通过这个Comparator,两个非常不同的对象可以被认为是"相同的"排序,即使它们是不相等的对象.我决定使用它hashCode作为决胜局,它出现了这样的事情:

    Collections.sort(details, new Comparator<MyObj>() {
        @Override
        public int compare(MyObj d1, MyObj d2) {

            if (d1.getDate() == null && d2.getDate() == null) {
                return d1.hashCode();
            } else if (d1.getDate() == null) {
                return -1;
            } else if (d2.getDate() == null) {
                return 1;
            }

            if (d1.getDate().before(d2.getDate())) return 1;
            else if (d1.getDate().after(d2.getDate())) return -1;
            else return d1.hashCode() - d2.hashCode();
        }
    });
Run Code Online (Sandbox Code Playgroud)

(我的回报可能是倒退,但这对这个问题并不重要)

这有必要吗?

编辑: 对于其他任何查看此问题的人,请考虑使用Google的订购API.上面的逻辑被替换为:

 return Ordering.<Date> natural().reverse().nullsLast().compare(d1.getDate(), d2.getDate());
Run Code Online (Sandbox Code Playgroud)

Lou*_*man 8

通过这个比较器,即使它们是不相等的物体,也可以认为两个非常不同的物体是"相同的"排序.

那真的没关系; 即使它们在任何其他意义上都不是"相等",两个对象的比较也是完全正常的. Collections.sort是一种稳定的排序,意味着比较相同的对象以它们进入的相同顺序出现; 这相当于只使用"输入中的索引"作为决胜局.

(另外,你的新版本Comparator实际上比原版更加破碎. return d1.hashCode()特别荒谬,并且由于溢出问题return d1.hashCode() - d2.hashCode()可能导致非传递性排序会破坏Collections.sort.除非两个整数都是非负的,否则哪个hashCodes不是,总是Integer.compare用来比较整数).