环境
java:1.7
前言
本来是不想写这篇的,但是最近老报这个错误,一开始,我以为解决了,后来发现不是那么回事
现在特意记录下
我的排序代码
我先贴出完整的排序代码:
/**
* 支持两个字段排序
* @param result
* @param order
* @param orderType
* @param twoOrder 第二排序字段
* @param twoType 第二排序顺序
* @return
* @author yutao
* @date 2018年5月24日下午3:00:03
*/
public static List<Map<String, Object>> resultOrder(List<Map<String, Object>> result, String order, Integer orderType,
final String twoOrder, final Integer twoType){
if(result == null || orderType == null){
return result;
}
if(orderType != -1){
orderType = 1;
}
final String orderKey = order;
final Integer oType = orderType;
Collections.sort(result, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
Object obj1 = o1.get(orderKey);
Object obj2 = o2.get(orderKey);
return commonOrder(orderKey, oType, obj1, obj2, twoOrder, twoType);
}
});
return result;
}
/**
* 公共的排序部分
* @param orderKey
* @param oType
* @param obj1
* @param obj2
* @param twoOrder
* @param twoType
* @return
* @author yutao
* @date 2018年5月24日下午3:19:37
*/
public static Integer commonOrder(final String orderKey, final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
//重点注意
if(obj1 == null && obj2 == null){
return 0;
}
if (obj1 == null) {
if(oType < 0){
return -oType;
}
return oType;
}
if (obj2 == null) {
if(oType < 0){
return oType;
}
return -oType;
}
if(obj1 instanceof Date && obj2 instanceof Date){
//日期排序
Date date1 = (Date)obj1;
Date date2 = (Date)obj2;
return longCompare(oType, date1.getTime(), date2.getTime(), twoOrder, twoType);
}else if(obj1 instanceof String && obj2 instanceof String){
//字符串排序
String str1 = obj1.toString();
String str2 = obj2.toString();
if(str1.compareTo(str2) < 0){
return -oType;
}else if(str1.compareTo(str2) == 0){
return 0;
}else if(str1.compareTo(str2) > 0){
return oType;
}
}else if((obj1 instanceof Double || obj1 instanceof Float) && (obj2 instanceof Double || obj2 instanceof Float)){
//浮点型排序
return doubleCompare(oType, obj1, obj2, twoOrder, twoType);
}else if((obj1 instanceof Long || obj1 instanceof Integer || obj1 instanceof Short || obj1 instanceof Byte) &&
(obj2 instanceof Long || obj2 instanceof Integer || obj2 instanceof Short || obj2 instanceof Byte)){
//整数型排序
return longCompare(oType, obj1, obj2, twoOrder, twoType);
}else if((obj1.getClass() != obj2.getClass()) && (obj1 instanceof Number && obj2 instanceof Number)){
//这种情况可能是,既有整数又有浮点数
return doubleCompare(oType, obj1, obj2, twoOrder, twoType);
}
return 0;
}
/**
* 整形比较大小
* @param oType
* @param obj1
* @param obj2
* @param twoOrder
* @param twoType
* @return
* @author yutao
* @date 2018年5月24日下午3:09:18
*/
private static int longCompare(final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
long d1 = Long.parseLong(obj1.toString());
long d2 = Long.parseLong(obj2.toString());
if(d1 < d2){
return -oType;
}else if(d1 == d2){
if(twoOrder != null && twoType != null){
//相等就使用第二字段排序
return commonOrder(twoOrder, twoType, obj1, obj2, null, null);
}
//相同的是否进行交互
return 0;
}else if(d1 > d2){
return oType;
}
return 0;
}
/**
* 浮点型比较大小
* @param oType
* @param obj1
* @param obj2
* @return
* @author yutao
* @date 2018年5月24日下午3:09:41
*/
private static int doubleCompare(final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
double d1 = Double.parseDouble(obj1.toString());
double d2 = Double.parseDouble(obj2.toString());
if(d1 < d2){
return -oType;
}else if(d1 == d2){
if(twoOrder != null && twoType != null){
//相等就使用第二字段排序
return commonOrder(twoOrder, twoType, obj1, obj2, null, null);
}
return 0;
}else if(d1 > d2){
return oType;
}
return 0;
}
分析
在JDK7以后,实现Comparable接口后,要满足一下三个特性:
1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。
2) 传递性:x>y,y>z,则 x>z。
3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同。
而我的代码中,因为有对象属性为null的判断,所以有下面这样的代码:
public static Integer commonOrder(final String orderKey, final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
if (obj1 == null) {
if(oType < 0){
return -oType;
}
return oType;
}
if (obj2 == null) {
if(oType < 0){
return oType;
}
return -oType;
}
// 以下代码省略。。。
这样的话,是不满足对称性的;
因为必须完善为null
的情况:
public static Integer commonOrder(final String orderKey, final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
//重点注意
if(obj1 == null && obj2 == null){
return 0;
}
if (obj1 == null) {
if(oType < 0){
return -oType;
}
return oType;
}
if (obj2 == null) {
if(oType < 0){
return oType;
}
return -oType;
}
// 以下代码省略。。。
有了上面的代码,就满足对称性了。