面對不斷變化的業務分組需求,傳統寫法導致大量樣板代碼。本文通過實戰場景展示如何結合 Java 8 Lambda 表達式與泛型,將「按姓名首字母分組」「按薪資區間分組」「按入職年份分組」等邏輯統一抽象,實現代碼復用與優雅表達。
public class Employee {
public String name;
public int age;
public char sex;
public String time; // 入職時間
public int salary;
}
按姓名首字母分組:
public static Map<Character, List<Employee>> groupByFirstChar(List<Employee> data) {
Map<Character, List<Employee>> result = new HashMap<>();
for (Employee e : data) {
Character c = e.name.charAt(0);
List<Employee> list = result.get(c);
if (list == null) {
list = new ArrayList<>();
result.put(c, list);
}
list.add(e);
}
return result;
}
按薪資區間分組邏輯幾乎相同,僅 Key 提取方式不同。隨著需求增加,代碼膨脹明顯。
觀察發現,唯一變化是 Employee -> Key 的轉換函數:
e -> e.name.charAt(0)e -> separate(e.salary)e -> getYear(e.time)定義函數式接口並泛型化分組邏輯:
interface GetKey<K> {
K getKey(Employee e);
}
public static <K> Map<K, List<Employee>> groupByKey(List<Employee> data, GetKey<K> getKey) {
Map<K, List<Employee>> result = new HashMap<>();
for (Employee e : data) {
K key = getKey.getKey(e);
List<Employee> list = result.get(key);
if (list == null) {
list = new ArrayList<>();
result.put(key, list);
}
list.add(e);
}
return result;
}
Map<Character, List<Employee>> result = groupByKey(data, new GetKey<Character>() {
@Override public Character getKey(Employee e) { return e.name.charAt(0); }
});
Java 8 Lambda 配合類型推斷,僅保留核心邏輯:
Map<Character, List<Employee>> byFirstChar = groupByKey(list, e -> e.name.charAt(0));
Map<String, List<Employee>> bySalary = groupByKey(list, e -> separate(e.salary));
e -> e.name.charAt(0) 即為 GetKey<Character> 的實現,參數類型、返回類型均由編譯器推斷。
利用 java.util.function.Function<T, R> 標準函數式接口,進一步泛型化數據元素類型:
public static <K, E> Map<K, List<E>> groupBy(
List<? extends E> data,
Function<? super E, ? extends K> fun
) {
Map<K, List<E>> result = new HashMap<>();
for (E e : data) {
K k = fun.apply(e);
List<E> list = result.get(k);
if (list == null) {
list = new ArrayList<>();
result.put(k, list);
}
list.add(e);
}
return result;
}
通配符 ? extends E、? super E 體現「生產者 extends,消費者 super」原則,確保類型安全與靈活性並存。此版本適用於任意集合元素類型與任意 Key 類型。
這正是 Java 8 賦予開發者的「更多選擇」——以聲明式風格處理集合操作,後續可進一步結合 Stream API 實現更流暢的數據處理管道。