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)
通过这个比较器,即使它们是不相等的物体,也可以认为两个非常不同的物体是"相同的"排序.
那真的没关系; 即使它们在任何其他意义上都不是"相等",两个对象的比较也是完全正常的. Collections.sort是一种稳定的排序,意味着比较相同的对象以它们进入的相同顺序出现; 这相当于只使用"输入中的索引"作为决胜局.
(另外,你的新版本Comparator实际上比原版更加破碎. return d1.hashCode()特别荒谬,并且由于溢出问题return d1.hashCode() - d2.hashCode()可能导致非传递性排序会破坏Collections.sort.除非两个整数都是非负的,否则哪个hashCodes不是,总是Integer.compare用来比较整数).