Java 8 引入了 Lambda 表達式Stream API,這讓 Java 程式的寫法變得更加簡潔、高效,特別適合處理集合(ListSetMap)中的大量數據。


🔥 1. Lambda 表達式

Lambda 是一種 簡短的匿名方法(函數),主要用於簡化「只有一個方法的介面」(例如 Functional Interface)的使用。

👉 為什麼需要 Lambda?

在 Java 8 之前,如果我們要傳遞一個「行為」給某個方法,通常會寫一個 匿名類別,例如:

java複製編輯// 傳統寫法:使用匿名類別
List<String> names = Arrays.asList("John", "Jane", "Jack");
Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});
System.out.println(names);

這樣的寫法很冗長,Lambda 表達式 讓這種寫法簡單許多:

java複製編輯// 使用 Lambda
List<String> names = Arrays.asList("John", "Jane", "Jack");
Collections.sort(names, (a, b) -> a.compareTo(b));
System.out.println(names);

這樣的 Lambda 表達式可以簡化程式碼,提高可讀性。


🔥 2. Stream API

Stream API 提供了一種 聲明式(Declarative)的方式來處理集合(ListSetMap),不需要手動寫 for 迴圈。

👉 為什麼需要 Stream API?

假設我們有一個 List<Integer>,要找出所有大於 10 的數字: 傳統寫法(使用 for 迴圈):

java複製編輯List<Integer> numbers = Arrays.asList(5, 10, 15, 20);
List<Integer> result = new ArrayList<>();
for (Integer num : numbers) {
    if (num > 10) {
        result.add(num);
    }
}
System.out.println(result); // [15, 20]

Stream API 寫法:

java複製編輯List<Integer> numbers = Arrays.asList(5, 10, 15, 20);
List<Integer> result = numbers.stream()
                              .filter(n -> n > 10)
                              .collect(Collectors.toList());
System.out.println(result); // [15, 20]

💡 優勢:

  • 不需要手動 for 迴圈
  • 只關心「做什麼」,不關心「怎麼做」(提高可讀性)
  • 可併行運算(Parallel Processing) 提高效能

🔥 3. Lambda + Stream API 強大組合

我們可以將 filter()map()forEach() 等方法鏈式呼叫,來對集合進行操作:

java複製編輯List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// 找出名字長度超過 3 的,轉換為大寫,並印出
names.stream()
     .filter(name -> name.length() > 3)  // 過濾
     .map(String::toUpperCase)           // 轉換
     .forEach(System.out::println);      // 輸出

結果:

nginx複製編輯ALICE
CHARLIE
DAVID

🔥 4. Stream API 主要方法

方法作用例子
filter(Predicate<T>)過濾符合條件的元素.filter(n -> n > 10)
map(Function<T, R>)轉換元素類型或值.map(String::toUpperCase)
sorted()排序.sorted()
distinct()去除重複值.distinct()
forEach(Consumer<T>)遍歷並執行動作.forEach(System.out::println)
collect(Collectors.toList())轉換回 List/Set/Map.collect(Collectors.toList())
reduce(BinaryOperator<T>)累加/合併.reduce(0, (a, b) -> a + b)

🔥 5. 進階應用

👉 計算數據:使用 reduce()

假設我們要對 List<Integer> 裡的數字求和:

java複製編輯List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(sum); // 15

👉 分組 & 統計:使用 groupingBy()

假設我們有一群人的名單,要按照姓名長度分類:

java複製編輯List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

Map<Integer, List<String>> grouped = names.stream()
    .collect(Collectors.groupingBy(String::length));

System.out.println(grouped);

結果:

json複製編輯{3=[Bob], 5=[Alice, David], 7=[Charlie]}

🎯 總結

技術作用例子
Lambda簡化匿名類別,使程式更簡潔(a, b) -> a + b
Stream API聲明式處理集合,不用寫 for 迴圈.filter(n -> n > 10).map(n -> n * 2)
方法鏈(Method Chaining)讓操作更簡潔,可讀性更高.sorted().map(String::toUpperCase).collect(...)