Comparator<T>实现自定义排序

应用目的

不在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方法,或者自己考虑相等的情况

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值