首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java ArrayList 排序全攻略:Comparable、Comparator、Lambda 與 Stream 實戰

     編輯:Java 相關知識

前言

ArrayList 是最高頻集合,排序是必備操作。本文涵蓋 自然序、定製序、多字段組合、降序、Java 8+ Lambda/Stream 五大場景,附完整可運行代碼。

場景一:基本類型 / String 自然序排序

List<String> countries = Arrays.asList("France", "USA", "India", "Spain", "England");
Collections.sort(countries);                    // 升序 [England, France, India, Spain, USA]
Collections.sort(countries, Collections.reverseOrder()); // 降序

原理:String 實現 Comparable<String>,按字典序比較。

場景二:自定義對象實現 Comparable(單一自然序)

public class JobCandidate implements Comparable<JobCandidate> {
    private String name, gender;
    private int age;
    // 構造器、Getter、toString 省略

    @Override
    public int compareTo(JobCandidate o) {
        // 年齡升序:避免減法溢出,用三元表達式
        return Integer.compare(this.age, o.age);
    }
}

// 使用
List<JobCandidate> list = ...;
Collections.sort(list);  // 按年齡升序

限制:類內部只能定義一種自然序,修改需改動源碼。

場景三:Comparator 定製多種排序策略(推薦)

public class JobCandidate {
    private String name, gender;
    private int age;
    // ...

    // 靜態工廠:年齡降序
    public static final Comparator<JobCandidate> BY_AGE_DESC =
        Comparator.comparingInt(JobCandidate::getAge).reversed();

    // 靜態工廠:姓名升序
    public static final Comparator<JobCandidate> BY_NAME_ASC =
        Comparator.comparing(JobCandidate::getName);
}
// 使用
Collections.sort(list, JobCandidate.BY_AGE_DESC);
Collections.sort(list, JobCandidate.BY_NAME_ASC);

優勢:策略外置、可組合、不侵入實體類、支持鏈式組合(thenComparing)。

場景四:多字段組合排序(年齡升序 → 姓名降序)

Comparator<JobCandidate> multi =
    Comparator.comparingInt(JobCandidate::getAge)
              .thenComparing(JobCandidate::getName, Comparator.reverseOrder());

Collections.sort(list, multi);

場景五:Java 8+ Lambda 與 Stream 一行式排序

// 原地排序
list.sort(Comparator.comparingInt(JobCandidate::getAge).reversed());

// Stream 生成新列表(不改動原列表)
List<JobCandidate> sorted = list.stream()
    .sorted(Comparator.comparing(JobCandidate::getName))
    .collect(Collectors.toList());

性能與選型建議

場景推薦方式複雜度
基本類型/String/包裝類Collections.sort / list.sortO(n log n)
實體類單一自然序實現 ComparableO(n log n)
多策略/第三方類/多字段Comparator 靜態常量 + 鏈式O(n log n)
需保留原列表/鏈式處理Stream.sortedO(n log n) + 額外空間

避坑指南

  1. 不要用減法比較整數:a - b 可能溢出,用 Integer.compare(a,b) 或 Comparator.comparingInt。
  2. Collections.sort 要求列表可變,Arrays.asList 返回固定長度列表會拋 UnsupportedOperationException,需 new ArrayList<>(Arrays.asList(...))。
  3. 並發環境下排序前加鎖或用 CopyOnWriteArrayList 快照排序。
  4. 大數據量(>10萬)考慮並行排序:Arrays.parallelSort(Java 8+)。

總結

默認用 Comparator 靜態工廠 + 方法引用,代碼最乾淨、擴展性最強。Comparable 僅用於實體類確有「自然業務序」時。Java 8+ 讓排序代碼變成了可讀的業務語句。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved