应用目的
不在SQL中进行order by排序,而在Java代码中对某一字段进行排序,目的是为了缓解数据库的查询压力
源码
外比较器
java.util.Comparator
public interface Comparator<T> {
/**
* Compares its two arguments for order.
* Returns a negative integer,zero, or a positive integer
* as the first argument is less than, equal to, or greater than the second.
**/
int compare(T o1, T o2);
}
项目例子
ComparatorDateTool源码
public class ComparatorTool implements Comparator<CourierInfo> {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public int compare(CourierInfo t1, CourierInfo t2) {
if ((t1==null && t2==null) ||
(StringUtils.isBlank(t1.getSignTime()) && StringUtils.isBlank(t2.getSignTime()))){
return 0;
}
if(t1==null || StringUtils.isBlank(t1.getSignTime())){
return 1;
}
if(t2==null || StringUtils.isBlank(t2.getSignTime())){
return -1;
}
Date d1, d2;
try {
d1 = format.parse(t1.getSignTime());
d2 = format.parse(t2.getSignTime());
} catch (Throwable e) {
// 解析出错,则不进行排序
return 0;
}
return d2.compareTo(d1);
}
}
ConsignDTO源码
package com.forezp;
public class ConsignDTO {
public String scantime; // 扫描时间
public String getScantime() {
return scantime;
}
public void setScantime(String scantime) {
this.scantime = scantime;
}
@Override
public String toString() {
return "ConsignDTO [scantime=" + scantime + "]";
}
}
DateStringDescTest源码
package com.forezp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 揽件扫描时间按时间降序排序,最近的日期显示在上面
*/
public class DateStringDescTest {
public static void main(String[] args) {
List<ConsignDTO> list = new ArrayList<ConsignDTO>();
ConsignDTO teacher = new ConsignDTO();
teacher.setScantime("2018/6/8 10:00:00");
ConsignDTO teacher2 = new ConsignDTO();
teacher2.setScantime("2018/6/2 10:00:00");
ConsignDTO teacher3 = new ConsignDTO();
teacher3.setScantime("2018/7/10 12:10:00");
ConsignDTO teacher4 = new ConsignDTO();
teacher4.setScantime("2018/7/10 16:00:00");
list.add(teacher);
list.add(teacher2);
list.add(teacher3);
list.add(teacher4);
// 排序前
System.out.println("=========排序前===========");
list.forEach(t -> System.out.println(t.toString()));
System.out.println("=========排序后===========");
ComparatorDateTool c = new ComparatorDateTool();
Collections.sort(list, c);
list.forEach(t -> System.out.println(t.toString()));
}
}
运行结果
=========排序前===========
ConsignDTO [scantime=2018/6/8 10:00:00]
ConsignDTO [scantime=2018/6/2 10:00:00]
ConsignDTO [scantime=2018/7/10 12:10:00]
ConsignDTO [scantime=2018/7/10 16:00:00]
=========排序后===========
ConsignDTO [scantime=2018/7/10 16:00:00]
ConsignDTO [scantime=2018/7/10 12:10:00]
ConsignDTO [scantime=2018/6/8 10:00:00]
ConsignDTO [scantime=2018/6/2 10:00:00]
简单写法
List tracesT = new ArrayList();
tracesT.add(baoTracesT);
Collections.sort(tracesT, new Comparator<TaoBaoTraces>() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private Date getBirthday(TaoBaoTraces m) {
if ((m == null) || (m.getTime() == null))
return null;
try {
return this.sdf.parse(m.getTime());
} catch (ParseException e) {
}
return null;
}
public int compare(TaoBaoTraces o1, TaoBaoTraces o2) {
Date d1 = getBirthday(o1);
Date d2 = getBirthday(o2);
if ((d1 == null) && (d2 == null))
return 0;
if (d1 == null)
return -1;
if (d2 == null)
return 1;
return d1.compareTo(d2);
}
});
常见报错
报错信息
java.lang.IllegalArgumentException: Comparison method violates its general contract!
解决方案
- 选择使用老版本的排序方法,在代码前面加上这么一句
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
- 判断排序两个相等返回0
可以用对象的compareTo方法,或者自己考虑相等的情况