java - 如何解决 Java Collections.sort() 比较方法违反其一般约定异常
问题描述
我正在使用 Collections.sort 根据时间字段按升序对列表进行排序。下面是代码
private String getShipmentInpickingTime(List<Shipments> shipments) {
logger.info("in getShipmentInpickingTime");
DateFormat sdf = new SimpleDateFormat("hh:mm");
Collections.sort(shipments, (o1, o2) -> {
try {
if ((!"null".equals(o1.getShipmentinpickingtime())
&& !StringUtils.isEmpty(o1.getShipmentinpickingtime()))
&& (!"null".equals(o2.getShipmentinpickingtime())
&& !StringUtils.isEmpty(o2.getShipmentinpickingtime()))) {
return sdf.parse(o1.getShipmentinpickingtime()).compareTo(sdf.parse(o2.getShipmentinpickingtime()));
}
} catch (ParseException e) {
e.printStackTrace();
}
int count1 = 0;
return count1;
});
这个方法抛出异常——
java.lang.IllegalArgumentException: Comparison method violates its general contract.
关于这个问题,我浏览了谷歌 - 它说我正在将更大的对象与更小的对象进行比较。我尝试颠倒对象的顺序,但没有运气。
解决方案
如果任何一个元素无法解析,您只捕获一次异常。
考虑以下时间的三批货物:
A - 12:34
B - 34:56
C - null
使用您的比较器,compare(A, C)
将返回 0,compare(B, C)
将返回 0,但compare(A, B)
将返回非零结果,从而违反了传递性的一般合同。
一种简单的方法是使用Comparator.comparing
语法分别解析每个元素:
DateFormat sdf = new SimpleDateFormat("hh:mm");
shipments.sort(Comparator.comparing(
Shipments::getShipmentinpickingtime,
Comparator.nullsLast(Comparator.comparing(time -> {
try {
if (!"null".equals(time) && !StringUtils.isEmpty(time)) {
return sdf.parse(time);
}
} catch (ParseException ignoe) {
// Not a valid time
}
return null;
})))
);
推荐阅读
- python - Python 任务栏任务
- javascript - 使用 NodeJS 模块导出的奇怪行为
- ssl - ispconfig3.1 无法颁发letsencrypt 证书
- sql - 如何列出 Informix 中的所有函数?
- amazon-web-services - AWS 中 Elastic Beanstalk 的替代品
- node.js - 在 cloud9 IDE 中运行节点时出错?
- python - 在 tkinter 的画布中重复显示文本
- linux - 传递环境变量不适用于 Docker
- http - 端点基本身份验证 VueJ
- asp.net - 使用 web.config 重命名产品页面