本文目录导读:

Java 方法引用案例详解
方法引用是 Lambda 表达式的简化写法,用 符号表示,下面通过实际案例来展示各种类型的方法引用。
方法引用的四种类型
| 类型 | 语法 | 对应 Lambda |
|---|---|---|
| 静态方法引用 | ClassName::staticMethod |
(args) -> ClassName.staticMethod(args) |
| 实例方法引用(特定对象) | instance::instanceMethod |
(args) -> instance.instanceMethod(args) |
| 实例方法引用(类类型) | ClassName::instanceMethod |
(obj, args) -> obj.instanceMethod(args) |
| 构造器引用 | ClassName::new |
(args) -> new ClassName(args) |
实战案例
案例1:静态方法引用
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class StaticMethodRef {
public static void main(String[] args) {
// 场景1:对列表进行排序
List<String> names = Arrays.asList("Tom", "Alice", "Bob", "Charlie");
// Lambda 写法
names.sort((s1, s2) -> String.compareToIgnoreCase(s1, s2));
// 方法引用写法(静态方法引用)
names.sort(String::compareToIgnoreCase);
System.out.println("排序结果: " + names); // [Alice, Bob, Charlie, Tom]
// 场景2:使用 Function 接口
Function<Integer, String> intToString = String::valueOf;
System.out.println(intToString.apply(123).length()); // 3
// 场景3:使用 Predicate 判断空字符串
Predicate<String> isEmpty = String::isEmpty;
System.out.println(isEmpty.test("")); // true
System.out.println(isEmpty.test("Hello")); // false
}
}
案例2:实例方法引用(特定对象)
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public class InstanceMethodRef {
public static void main(String[] args) {
// 创建一个 StringBuilder 对象
StringBuilder sb = new StringBuilder("Hello ");
// 场景1:Consumer 接口 - 对特定对象的方法引用
Consumer<String> appendToSb = sb::append;
appendToSb.accept("World!");
System.out.println(sb.toString()); // Hello World!
// 场景2:Function 接口
List<String> names = List.of("Apple", "Banana", "Cherry");
// Lambda 写法
Function<String, Integer> lenLambda = (s) -> s.length();
// 方法引用写法(更简洁,使用特定对象的方法)
Function<String, Integer> lenRef = String::length; // 这是类类型实例方法引用
System.out.println(names.stream()
.map(String::length) // 类类型实例方法引用
.toList()); // [5, 6, 6]
// 场景3:特定对象的方法引用
List<String> toUpper = new ArrayList<>(List.of("hello", "world"));
System.out.println(toUpper.stream()
.map(String::toUpperCase)
.toList()); // [HELLO, WORLD]
}
}
案例3:实例方法引用(类类型 - 需要参数)
import java.util.Arrays;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Function;
public class ClassInstanceMethodRef {
public static void main(String[] args) {
// 场景1:比较两个字符串(忽略大小写)
List<String> words = Arrays.asList("Apple", "banana", "Cherry", "apple");
// 使用 BiPredicate 接口(接收两个参数)
BiPredicate<String, String> equalsIgnoreCase = String::equalsIgnoreCase;
System.out.println("Apple 与 apple 相等?: " +
equalsIgnoreCase.test("Apple", "apple")); // true
// 场景2:查找列表中是否存在特定元素
boolean hasApple = words.stream()
.anyMatch("apple"::equalsIgnoreCase); // 特定对象实例方法引用
System.out.println("列表包含 apple: " + hasApple); // true
// 场景3:复杂对象的方法引用
List<Person> persons = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 35)
);
// 将 Person 对象映射为姓名
Function<Person, String> getName = Person::getName;
System.out.println("人员姓名: " + persons.stream()
.map(getName)
.toList()); // [Alice, Bob, Charlie]
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
案例4:构造器引用
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
public class ConstructorRef {
public static void main(String[] args) {
// 场景1:无参构造器引用
Supplier<List<String>> listFactory = ArrayList::new;
List<String> list = listFactory.get();
list.add("Hello");
System.out.println("创建的空列表: " + list); // [Hello]
// 场景2:有参构造器引用
Function<String, StringBuilder> sbFactory = StringBuilder::new;
StringBuilder sb = sbFactory.apply("Hello World");
System.out.println("构造器创建: " + sb.toString()); // Hello World
// 场景3:数组构造器引用
Function<Integer, String[]> stringArray = String[]::new;
String[] arr = stringArray.apply(5);
System.out.println("创建数组长度: " + arr.length); // 5
// 场景4:结合 Stream 使用
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Student> students = names.stream()
.map(Student::new) // 构造器引用
.toList();
students.forEach(System.out::println);
}
}
class Student {
private String name;
public Student(String name) {
this.name = name;
System.out.println("为学生创建了: " + name);
}
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + '}';
}
}
案例5:综合实战 - 员工数据处理
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ComprehensiveDemo {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("张伟", 28, 18000, "技术部"),
new Employee("李娜", 35, 22000, "产品部"),
new Employee("王强", 42, 30000, "管理部"),
new Employee("赵敏", 24, 15000, "技术部"),
new Employee("钱进", 38, 25000, "市场部")
);
System.out.println("=== 原始数据 ===");
employees.forEach(System.out::println);
// 场景1:排序(方法引用)
System.out.println("\n=== 按年龄排序 ===");
employees.stream()
.sorted(Comparator.comparingInt(Employee::getAge))
.forEach(System.out::println);
// 场景2:工资过滤 + 统计
System.out.println("\n=== 工资超过20000的员工 ===");
double avgSalary = employees.stream()
.filter(e -> e.getSalary() > 20000)
.mapToInt(Employee::getSalary)
.average()
.orElse(0);
System.out.println("平均工资: " + avgSalary);
// 场景3:按部门分组
System.out.println("\n=== 按部门分组 ===");
Map<String, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
byDept.forEach((dept, empList) -> {
System.out.println(dept + ": " + empList.size() + "人");
});
// 场景4:获取所有姓名
System.out.println("\n=== 员工姓名 ===");
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
// 场景5:自定义比较器
System.out.println("\n=== 按工资降序 ===");
employees.stream()
.sorted(Comparator.comparingInt(Employee::getSalary).reversed())
.map(Employee::getName)
.forEach(e -> System.out.println("员工: " + e));
}
}
class Employee {
private String name;
private int age;
private int salary;
private String department;
public Employee(String name, int age, int salary, String department) {
this.name = name;
this.age = age;
this.salary = salary;
this.department = department;
}
// Getters
public String getName() { return name; }
public int getAge() { return age; }
public int getSalary() { return salary; }
public String getDepartment() { return department; }
@Override
public String toString() {
return String.format("%s(%d岁,工资%d,%s)", name, age, salary, department);
}
}
方法引用 vs Lambda 对照表
// 1. 静态方法引用
Function<Integer, String> f1 = String::valueOf; // 方法引用
Function<Integer, String> f2 = i -> String.valueOf(i); // Lambda
// 2. 实例方法引用(直接调用)
List<String> list = List.of("a", "b");
list.forEach(System.out::println); // 方法引用
list.forEach(s -> System.out.println(s)); // Lambda
// 3. 对象引用(比较)
Comparator<String> c1 = String::compareToIgnoreCase; // 方法引用
Comparator<String> c2 = (a, b) -> a.compareToIgnoreCase(b); // Lambda
// 4. 构造器引用
Supplier<List<String>> s1 = ArrayList::new; // 方法引用
Supplier<List<String>> s2 = () -> new ArrayList<>(); // Lambda
使用建议
✅ 适合使用方法引用:
- 已有现成的方法直接匹配函数式接口
- 代码更加简洁、易读
- 标准库中如
Stream操作
❌ 不适合使用方法引用:
- 方法调用需要额外参数(非直接匹配)
- Lambda 中代码量超过一行
- 需要进行逻辑判断或计算
// 反例:方法引用反而更复杂
Function<String, String> f = s -> {
String upper = s.toUpperCase();
return upper + "-suffix";
}; // 这种情况必须用 Lambda
方法引用的核心价值在于简化代码,让代码更具可读性,选择标准:
- 方法恰好匹配接口参数 → 使用静态引用
- 需要对对象进行操作 → 使用实例引用
- 需要创建新对象 → 使用构造器引用
- 逻辑复杂或需要额外处理 → 继续使用 Lambda
掌握方法引用的关键是要理解函数式接口的参数传递规则,当方法签名与接口方法签名匹配时,就可以使用 简化代码。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播