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

Java 8 Lambda 與泛型實戰:提取通用分組邏輯、Function 接口與類型推斷

     編輯:Java 綜合教學

Java 8 Lambda 與泛型實戰:提取通用分組邏輯、Function 接口與類型推斷

本文通過「員工數據多維度分組」實戰,展示如何用 Lambda 表達式 + 泛型消除重複代碼,並進階到 Function 標準函數式接口與通配符邊界。

場景:員工列表多維分組

class Employee {
    String name; int age; char sex; String time; int salary;
    // getter/setter...
}
List data = Arrays.asList(e1, e2, e3...);

傳統寫法:重複的分組邏輯

// 按姓名首字母分組
Map> groupByName = new HashMap<>();
for (Employee e : data) {
    Character k = e.getName().charAt(0);
    groupByName.computeIfAbsent(k, x -> new ArrayList<>()).add(e);
}

// 按薪資區間分組
Map> groupBySalary = new HashMap<>();
for (Employee e : data) {
    String k = salaryRange(e.getSalary()); // 5000以下/5000-10000...
    groupBySalary.computeIfAbsent(k, x -> new ArrayList<>()).add(e);
}
// ... 入職年份、部門等 N 種分組,邏輯 90% 相同

提取通用方法:自定義函數式接口 + 泛型

@FunctionalInterface
interface KeyExtractor {
    K extract(E e);
}

static  Map> groupBy(List data, KeyExtractor extractor) {
    Map> result = new HashMap<>();
    for (E e : data) {
        K key = extractor.extract(e);
        result.computeIfAbsent(key, k -> new ArrayList<>()).add(e);
    }
    return result;
}

// 調用
Map> byName = groupBy(data, e -> e.getName().charAt(0));
Map> bySalary = groupBy(data, e -> salaryRange(e.getSalary()));
Map> byYear = groupBy(data, e -> entryYear(e.getTime()));

進階:使用 java.util.function.Function

JDK 內置 Function 等價於 KeyExtractor,更通用:

static  Map> groupBy(List data, Function mapper) {
    Map> result = new HashMap<>();
    for (E e : data) {
        K key = mapper.apply(e);
        result.computeIfAbsent(key, k -> new ArrayList<>()).add(e);
    }
    return result;
}

// 調用更簡潔,類型推斷自動完成
Map> byName = groupBy(data, e -> e.getName().charAt(0));
Map> bySalary = groupBy(data, e -> salaryRange(e.getSalary()));

通配符邊界解析

  • List:生產者 (Producer) —— 只讀取 E 及其子類,不可寫入 (PECS 原則)。
  • Function:消費者 (Consumer) —— 接受 E 及其父類,返回 K 及其子類。

Stream API 替代方案

Map> byName = data.stream()
    .collect(Collectors.groupingBy(e -> e.getName().charAt(0)));

Stream 內部已處理泛型邊界,日常開發首選;手寫通用工具方法時理解泛型邊界更有幫助。

總結

  1. Lambda 只關心「參數 → 返回值」,消除了匿名內部類樣板代碼。
  2. 泛型 + 函數式接口 = 可復用的演算法骨架。
  3. Function 是標準契約,優於自定義接口。
  4. PECS 原則指導通配符使用:Producer Extends, Consumer Super。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved