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());

輸出結果:

image

二、實現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());
    }
}

輸出結果:
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM