在 Java 開發中,排序是處理資料最基礎也最常見的操作之一。無論是基本類型陣列、集合中的物件,還是檔案列表,Java 都提供了豐富的 API 讓我們輕鬆完成排序。本文將從基礎陣列排序切入,逐步深入到物件排序、自訂比較器以及檔案排序的實戰範例,並附上完整可執行的程式碼。
Java 的 java.util.Arrays 類提供了靜態 sort() 方法,可對基本類型陣列進行原地排序,預設為升序。
int[] arr = {2, 3, 1, 10, 7, 4};
System.out.print("排序前: ");
for (int i : arr) System.out.print(i + " ");
System.out.println();
Arrays.sort(arr);
System.out.print("排序後: ");
for (int i : arr) System.out.print(i + " ");
// 輸出: 1 2 3 4 7 10
說明: 排序結果為升序。對於基本類型,Arrays.sort 使用雙軸快速排序,效能極佳。
若要排序自訂物件,該類別必須實作 java.lang.Comparable<T> 介面並覆寫 compareTo(T o) 方法。回傳值規則:
class Programmer implements Comparable<Programmer> {
private String name;
private String language;
private double pay;
public Programmer(String name, String language, double pay) {
this.name = name;
this.language = language;
this.pay = pay;
}
@Override
public int compareTo(Programmer other) {
// 依薪資升序排序
return Double.compare(this.pay, other.pay);
}
@Override
public String toString() {
return "{name: " + name + ", language: " + language + ", money: " + pay + "}";
}
}
List<Programmer> list = new ArrayList<>();
list.add(new Programmer("張三", "C", 12000));
list.add(new Programmer("李四", "Java", 200));
list.add(new Programmer("王五", "C++", 5000));
list.add(new Programmer("錢六", "VB", 3000));
System.out.println("排序前: " + list);
Collections.sort(list);
System.out.println("排序後: " + list);
// 輸出依薪資從低到高排列
提示: 許多 JDK 內建類別(如 String、Integer、Date)已實作 Comparable,可直接排序。
當類別無法修改(如第三方類別)、或需多種排序規則(如檔案按名稱、大小、修改時間排序)時,使用 java.util.Comparator 介面。這是策略模式的經典應用。
int compare(T o1, T o2):比較兩個物件大小boolean equals(Object obj):判斷比較器是否相等(通常直接回傳 true)class FileUtils {
// 按最後修改時間排序
static class ComparatorByLastModified implements Comparator<File> {
@Override
public int compare(File f1, File f2) {
long diff = f1.lastModified() - f2.lastModified();
return Long.compare(diff, 0);
}
}
// 按檔案大小排序
static class ComparatorBySize implements Comparator<File> {
@Override
public int compare(File f1, File f2) {
long diff = f1.length() - f2.length();
return Long.compare(diff, 0);
}
}
}
File dir = new File("C:\\temp");
File[] files = dir.listFiles();
// 1. 預設按名稱排序(File 實作了 Comparable)
Arrays.sort(files);
System.out.println("按名稱排序: " + Arrays.toString(files));
// 2. 按大小排序
Arrays.sort(files, new FileUtils.ComparatorBySize());
System.out.println("按大小排序: " + Arrays.toString(files));
// 3. 按修改時間排序
Arrays.sort(files, new FileUtils.ComparatorByLastModified());
System.out.println("按修改時間排序: " + Arrays.toString(files));
以下整合所有範例,可直接複製執行:
import java.io.*;
import java.util.*;
public class TestSort {
public static void main(String[] args) {
sortSimpleType();
sortComparable();
sortComparator();
}
static void sortSimpleType() {
int[] arr = {2, 3, 1, 10, 7, 4};
System.out.println("=== 基本類型排序 ===");
System.out.print("排序前: ");
for (int i : arr) System.out.print(i + " ");
System.out.println();
Arrays.sort(arr);
System.out.print("排序後: ");
for (int i : arr) System.out.print(i + " ");
System.out.println("\n");
}
static void sortComparable() {
List<Programmer> list = new ArrayList<>();
list.add(new Programmer("張三", "C", 12000));
list.add(new Programmer("李四", "Java", 200));
list.add(new Programmer("王五", "C++", 5000));
list.add(new Programmer("錢六", "VB", 3000));
System.out.println("=== 物件排序 ===");
System.out.println("排序前: " + list);
Collections.sort(list);
System.out.println("排序後: " + list + "\n");
}
static void sortComparator() {
File dir = new File("C:\\java"); // 請換成實際存在的目錄
File[] files = dir.listFiles();
if (files == null) return;
System.out.println("=== 檔案多維度排序 ===");
System.out.println("排序前: " + Arrays.toString(files));
Arrays.sort(files);
System.out.println("按名稱: " + Arrays.toString(files));
Arrays.sort(files, new FileUtils.ComparatorBySize());
System.out.println("按大小: " + Arrays.toString(files));
Arrays.sort(files, new FileUtils.ComparatorByLastModified());
System.out.println("按修改時間: " + Arrays.toString(files));
}
}
class Programmer implements Comparable<Programmer> {
private String name, language;
private double pay;
public Programmer(String name, String language, double pay) {
this.name = name; this.language = language; this.pay = pay;
}
@Override public int compareTo(Programmer o) {
return Double.compare(this.pay, o.pay);
}
@Override public String toString() {
return "{name:" + name + ", lang:" + language + ", pay:" + pay + "}";
}
}
class FileUtils {
static class ComparatorByLastModified implements Comparator<File> {
@Override public int compare(File f1, File f2) {
return Long.compare(f1.lastModified(), f2.lastModified());
}
}
static class ComparatorBySize implements Comparator<File> {
@Override public int compare(File f1, File f2) {
return Long.compare(f1.length(), f2.length());
}
}
}
| 場景 | 推薦做法 | 關鍵類別/介面 |
|---|---|---|
| 基本類型陣列 | Arrays.sort() | java.util.Arrays |
| 物件集合,單一固定排序規則 | 實作 Comparable,用 Collections.sort() | java.lang.Comparable |
| 物件集合,多種排序規則或無法修改類別 | 實作 Comparator,用 Collections.sort(list, comparator) | java.util.Comparator |
| 陣列物件排序 | Arrays.sort(array, comparator) | java.util.Arrays |
善用 Java 內建排序機制,不僅程式碼簡潔,效能也經過高度優化。除非有極特殊需求,否則不要自行實作排序演算法。