一、先看你天天写的代码
java
运行
userList.stream()
.map(User::getName)
.collect(Collectors.toList());
你只需要先记住一句话:
User::getName 就是 方法引用
等价于 Lambda:
java
运行
user -> user.getName()
二、从头拆解
1. 先看 User 类
你自己写的实体类:
java
运行
class User {
private String name;
private int age;
public String getName() {
return name;
}
}
getName() 是 User 对象的普通成员方法作用:拿到这个用户的名字
2. Lambda 原始写法
map 需要的是 **Function<User, String>**意思:传入一个 User,返回一个 String。
最原始完整写法:
java
运行
.map( (User user) -> {
return user.getName();
} )
简化 Lambda:
java
运行
.map(user -> user.getName())
3. 方法引用简写:User::getName
Java 允许你直接简写:对象调用的方法,直接写成 类名::方法名
java
运行
.map(User::getName)
三、到底是什么含义?(人话版)
遍历流里每一个 User 对象调用这个对象的
getName()方法把返回的名字拿出来
完全等同于:
java
运行
for(User u : userList){
String name = u.getName();
}
四、结合你之前所有知识点串起来(超级重要)
你前面学过的所有东西全部打通了:
- **Function<T,R>**有入参、有返回值
User进,String出 - map(Function)作用就是转换、提取属性
- user -> user.getName() (Lambda)
- User::getName (方法引用,简写版)
二者100% 完全等价,没有任何区别。
五、举一反三,所有你见过的方法引用全部归类
我把你这几天遇到的所有 :: 全部整理好,一眼分清:
1. 对象实例方法引用(最常用,90% 开发都用这个)
格式:类名::成员方法
java
运行
User::getName // user -> user.getName()
User::getAge // user -> user.getAge()
String::toUpperCase // s -> s.toUpperCase()
2. 静态方法引用
格式:类名::静态方法
java
运行
Integer::sum // (a,b)->Integer.sum(a,b)
Integer::max // (a,b)->Integer.max(a,b)
Integer::intValue // x -> x.intValue()
3. 构造方法引用
java
运行
User::new // () -> new User()
4. 普通对象方法引用
java
运行
System.out::println // s -> System.out.println(s)
六、全部对比,你所有疑问一次性清零
我把你所有问过的代码全部放一起对比,你瞬间融会贯通:
- Consumer
java
运行
.forEach(System.out::println)
// 等价 s -> System.out.println(s)
- Function(提取属性,你现在这个)
java
运行
.map(User::getName)
// 等价 user -> user.getName()
- Function(拆箱)
java
运行
.mapToInt(Integer::intValue)
// 等价 x -> x.intValue()
- BinaryOperator(reduce 运算)
java
运行
.reduce(Integer::sum)
// 等价 (a,b) -> Integer.sum(a,b)
.reduce(Integer::max)
// 等价 (a,b) -> Integer.max(a,b)
七、终极一句话总结
User::getName
遍历每一个 User 对象,调用它的 getName (),提取出用户名