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

Java 函數式編程(九):Comparator 函數式重構與鏈式比較器

     編輯:Java 相關知識

前言

Comparator 在 Java 8 成為函數式接口(單一抽象方法 compare(T o1, T o2)),配合 Lambda 與方法引用,排序代碼從「匿名內部類地獄」蛻變為流暢的鏈式表達。本文演示從基礎排序到多級組合、極值查找的完整實戰。

領域模型:Person

class Person {
    private final String name;
    private final int age;
    public Person(String name, int age) { this.name = name; this.age = age; }
    public String getName() { return name; }
    public int getAge() { return age; }
    public int ageDifference(Person other) { return age - other.age; }
    @Override public String toString() { return String.format("%s - %d", name, age); }
}

基礎排序:Lambda vs 方法引用

按年齡升序

List<Person> ascendingAge = people.stream()
    .sorted((p1, p2) -> p1.ageDifference(p2)) // Lambda
    .collect(toList());

方法引用優化(參數路由:p1 作為調用者,p2 作為參數)

List<Person> ascendingAge = people.stream()
    .sorted(Person::ageDifference) // 極簡
    .collect(toList());

輸出:

John - 20
Sara - 21
Jane - 21
Greg - 35

Comparator 重用與反轉

Comparator<Person> byAgeAsc = Comparator.comparingInt(Person::getAge);
Comparator<Person> byAgeDesc = byAgeAsc.reversed(); // 零成本反轉

people.stream().sorted(byAgeAsc).collect(toList());
people.stream().sorted(byAgeDesc).collect(toList());

reversed() 是默認方法,內部交換參數順序,屬於高階函數(返回新 Comparator)。

按名字排序:comparing 工廠方法

Function<Person, String> byName = Person::getName;
people.stream()
    .sorted(comparing(byName)) // 靜態導入 comparing
    .collect(toList());

輸出(字典序):

Greg - 35
Jane - 21
John - 20
Sara - 21

多級比較:thenComparing 組合

Function<Person, Integer> byAge = Person::getAge;
Function<Person, String> byName = Person::getName;

List<Person> result = people.stream()
    .sorted(comparing(byAge).thenComparing(byName)) // 先年齡後名字
    .collect(toList());

輸出:

John - 20
Jane - 21
Sara - 21
Greg - 35

極值查找:min/max 配合 Optional

people.stream()
    .min(Person::ageDifference)
    .ifPresent(p -> System.out.println("Youngest: " + p)); // Youngest: John - 20

people.stream()
    .max(Person::ageDifference)
    .ifPresent(p -> System.out.println("Eldest: " + p));   // Eldest: Greg - 35

min/max 返回 Optional,避免空指針,配合 ifPresent 安全消費。

Comparator 靜態工廠方法速查表

方法說明示例
comparing(keyExtractor)按提取鍵自然順序comparing(Person::getName)
comparing(keyExtractor, keyComparator)按提取鍵自定義比較器comparing(Person::getAge, Comparator.reverseOrder())
comparingInt/Long/Double(keyExtractor)基本類型專用,避免裝箱comparingInt(Person::getAge)
thenComparing(...)次級比較器comparingInt(Person::getAge).thenComparing(Person::getName)
reversed()反轉順序byAge.reversed()
nullsFirst/Last(comparator)空值優先/靠後nullsFirst(comparing(Person::getName))

總結

Java 8 將 Comparator 升級為函數式接口,配合 comparing、thenComparing、reversed 等默認方法,構建出強大的比較器 DSL。配合 Stream sorted、min、max,排序與極值查找代碼既極簡又類型安全。下一篇將深入 Collectors 進階聚合技巧。

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