java中list集合按物件屬性進行排序
阿新 • • 發佈:2021-06-18
在日常搬磚中,我們可能會需要對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());
輸出結果:
二、實現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());
}
}
輸出結果: