java中list集合按对象属性进行排序

在日常搬砖中,我们可能会需要对List中自定义的一些对象进行排序,但java是不知道我们的对象是需要怎么排序,因此我们得自己写排序的规则。

jdk提供了两个对象比较的接口Comparable和Comparator,通过实现接口可以对两个或多个对象进行比较,确认它们的大小关系或排列顺序。

下面假如有一个业务报表需求:需要按对象的时间字段optime倒序排列,假设数据库中返回的数据是乱序,为了减少查询时间不使用sql排序,在程序中进行排序。

一、实现Comparable接口

需要排序对象的类实现Comparable接口重写compareTo方法。

这种方式需要对原来的类上进行修改。

Comparable可以理解为,原始对象类实现了Comparable接口有了比较的能力,你给我一个对象我就可以和它比较。

报表类Report:

public class Report implements Comparable<Report> {
    private String account;
    private String opetime;
    private String channel;
    private BigDecimal amount;
    private String nodeno;
    private String nodetag;
    public Report(String account, String opetime, String channel, BigDecimal amount, String nodeno, String nodetag) {
        this.account = account;
        this.opetime = opetime;
        this.channel = channel;
        this.amount = amount;
        this.nodeno = nodeno;
        this.nodetag = nodetag;
    }
    // getter和sertter省略...
    
    @Override
    public int compareTo(Report o) {
        // 格式化时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date dt1 = null;
        Date dt2 = null;
        try {
            dt1 = sdf.parse(getOpetime());
            dt2 = sdf.parse(o.getOpetime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 用时间字段进行比较
        if (dt1.compareTo(dt2) > 0) {
            return -1; // 交换-1和1的位置就可以控制正序和倒序
        }else if (dt1.compareTo(dt2) < 0){
            return 1;
        }else{
            return 0;
        }
    }

测试:

用Collections类中的sort方法对List进行排序。

// 模拟数据库中返回的数据
        ArrayList<Report> reports = new ArrayList<>();
        reports.add(new Report("50030001", "2021-05-23 19:08:26", "1004",new BigDecimal(103),"50000001","亚洲网点"));
        reports.add(new Report("50030231", "2021-04-23 11:08:26", "1004",new BigDecimal(20),"50000001","北欧洲网点"));
        reports.add(new Report("50034341", "2021-03-23 14:08:26", "1005",new BigDecimal(90),"50000001","非洲网点"));
        reports.add(new Report("50034341", "2021-02-23 14:08:26", "1005",new BigDecimal(90),"50000001","非洲网点"));
        reports.add(new Report("50036547", "2021-06-23 12:08:26", "1004",new BigDecimal(88),"50000001","美洲网点"));
        reports.add(new Report("50033698", "2021-01-23 08:08:26", "1003",new BigDecimal(1000),"50000001","711网点"));

        System.out.println(reports.toString());
        Collections.sort(reports); // 对象自己有比较的能力不需要传比较器
        System.out.println("--------------------------------------------排序前后分割线-----------------------------------------------------");
        System.out.println(reports.toString());

输出结果:

java中list集合按对象属性进行排序

二、实现Comparator接口

如果不想在原有的类上进行修改,那么可以单独写一个比较器,比较器类需要实现Comparator接口并重写compare方法,比较方法和compareTo差不多,但需要传输两个对象进行比较。

Comparator可以理解为,原始对象不会比较,我通过创建一个第三方的比较器强制对它们进行比较。

/

ReportComparator比较器:

public class ReportComparator implements Comparator<Report> {
    @Override
    public int compare(Report o1, Report o2) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date dt1 = null;
        Date dt2 = null;
        try {
            dt1 = sdf.parse(o1.getOpetime());
            dt2 = sdf.parse(o2.getOpetime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (dt1.compareTo(dt2) > 0) {
            return -1;
        }else if (dt1.compareTo(dt2) < 0){
            return 1;
        }else{
            return 0;
        }
    }
}

测试:

public class DateTest {
    public static void main(String[] args) throws ParseException {
        // 模拟数据库中返回的数据
        ArrayList<Report> reports = new ArrayList<>();
        reports.add(new Report("50030001", "2021-05-23 19:08:26", "1004",new BigDecimal(103),"50000001","亚洲网点"));
        reports.add(new Report("50030231", "2021-04-23 11:08:26", "1004",new BigDecimal(20),"50000001","北欧洲网点"));
        reports.add(new Report("50034341", "2021-03-23 14:08:26", "1005",new BigDecimal(90),"50000001","非洲网点"));
        reports.add(new Report("50034341", "2021-02-23 14:08:26", "1005",new BigDecimal(90),"50000001","非洲网点"));
        reports.add(new Report("50036547", "2021-06-23 12:08:26", "1004",new BigDecimal(88),"50000001","美洲网点"));
        reports.add(new Report("50033698", "2021-01-23 08:08:26", "1003",new BigDecimal(1000),"50000001","711网点"));

        System.out.println(reports.toString());
        Collections.sort(reports, new ReportComparator()); // 传入一个比较器,这个比较器也可以写匿名内部类实现
        System.out.println("--------------------------------------------排序前后分割线-----------------------------------------------------");
        System.out.println(reports.toString());
    }
}

输出结果:
java中list集合按对象属性进行排序

上一篇:Stimulsoft Reports如何创建新的数据转换、编辑数据转换


下一篇:mybati报错ReflectionException