Lambda can be replaced with method reference
Lambda can be replaced with method reference
Lambda can be replaced with method reference
Lambda can be replaced with method reference
Lambda 可以用方法參考 (Method Reference) 替換
當 Lambda 表達式只是簡單地呼叫一個方法時,可以用方法參考讓程式碼更簡潔。
- 靜態方法參考
Lambda → 靜態方法參考
java// ❌ Lambda 寫法
list.stream()
.map(s -> String.valueOf(s))
.collect(toList());
// ✅ 方法參考寫法
list.stream()
.map(String::valueOf)
.collect(toList());
java// ❌ Lambda 寫法
numbers.stream()
.filter(n -> Objects.nonNull(n))
.collect(toList());
// ✅ 方法參考寫法
numbers.stream()
.filter(Objects::nonNull)
.collect(toList());
2. 實例方法參考
特定物件的實例方法
java// ❌ Lambda 寫法
strings.forEach(s -> System.out.println(s));
// ✅ 方法參考寫法
strings.forEach(System.out::println);
String prefix = “Hello “;
// ❌ Lambda 寫法
list.stream()
.map(name -> prefix.concat(name))
.collect(toList());
// ✅ 方法參考寫法
list.stream()
.map(prefix::concat)
.collect(toList());
任意物件的實例方法
java// ❌ Lambda 寫法
strings.stream()
.map(s -> s.toLowerCase())
.collect(toList());
// ✅ 方法參考寫法
strings.stream()
.map(String::toLowerCase)
.collect(toList());
java// ❌ Lambda 寫法
people.stream()
.sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
.collect(toList());
// ✅ 方法參考寫法
people.stream()
.sorted(Comparator.comparing(Person::getName))
.collect(toList());
3. 建構子參考
java// ❌ Lambda 寫法
strings.stream()
.map(s -> new Person(s))
.collect(toList());
// ✅ 建構子參考寫法
strings.stream()
.map(Person::new)
.collect(toList());
java// ❌ Lambda 寫法
Stream.generate(() -> new ArrayList<>())
.limit(5)
.collect(toList());
// ✅ 建構子參考寫法
Stream.generate(ArrayList::new)
.limit(5)
.collect(toList());
4. 陣列建構子參考
java// ❌ Lambda 寫法
String[] array = list.stream()
.toArray(size -> new String[size]);
// ✅ 陣列建構子參考寫法
String[] array = list.stream()
.toArray(String[]::new);
5. 實際應用範例
集合處理
List
// ❌ Lambda 寫法
names.stream()
.filter(name -> StringUtils.isNotBlank(name))
.map(name -> name.toUpperCase())
.forEach(name -> System.out.println(name));
// ✅ 方法參考寫法
names.stream()
.filter(StringUtils::isNotBlank)
.map(String::toUpperCase)
.forEach(System.out::println);
排序操作
List
// ❌ Lambda 寫法
people.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge()));
// ✅ 方法參考寫法
people.sort(Comparator.comparing(Person::getAge));
Optional 處理
Optional
// ❌ Lambda 寫法
optional.map(s -> s.length())
.filter(len -> len > 5)
.ifPresent(len -> System.out.println(len));
// ✅ 方法參考寫法
optional.map(String::length)
.filter(len -> len > 5)
.ifPresent(System.out::println);
6. 何時不能使用方法參考
需要額外參數
java// ❌ 不能用方法參考
list.stream().map(s -> s.substring(1)); // 需要參數
// ❌ 不能用方法參考
list.stream().filter(s -> s.length() > 3); // 需要比較
需要額外邏輯
java// ❌ 不能用方法參考
list.stream().map(s -> {
System.out.println(“Processing: “ + s);
return s.toUpperCase();
});
方法簽章不匹配
java// ❌ 不能用方法參考
BiFunction<String, String, String> func = (a, b) -> a.concat(b);
// String::concat 的簽章是 String concat(String),不匹配 BiFunction
7. IDE 自動轉換
IntelliJ IDEA
會自動提示可以轉換為方法參考
使用 Alt+Enter → “Replace lambda with method reference”
Eclipse
也有類似的快速修復功能
可以批量轉換整個專案
- 可讀性考量
✅ 推薦使用方法參考的情況
java// 清楚直觀
list.forEach(System.out::println);
names.stream().map(String::toUpperCase);
people.sort(Comparator.comparing(Person::getName));
⚠️ 謹慎使用的情況
java// 可能不夠直觀,Lambda 可能更清楚
Function<String, Integer> func = Integer::parseInt; // OK
Function<String, Boolean> func2 = Boolean::valueOf; // 可能用 Lambda 更清楚
總結對照表
Lambda 類型Lambda 寫法方法參考寫法
靜態方法x -> Math.abs(x) Math::abs
實例方法(特定物件)s -> obj.method(s) obj::method
實例方法(任意物件)s -> s.method() String::method
建構子x -> new Obj(x) Obj::new
陣列建構子size -> new int[size] int[]::new
建議:當 Lambda 只是簡單地呼叫方法時,使用方法參考可以讓程式碼更簡潔易讀!