Stream流&&lambda表达式&&引用&&函数式接口

引用并不是函数式接口的高级用法,引用和Lambda是孪生兄弟>

1.前言

本文适合了解过Stream流和Lambda表示式和引用的读者

2.体验
1
2
3
4
5
//根据id列表获数据库中的用户列表
List<User> userList = accountService.getUserList( userIds);

//使用stream流将user当中的id,和username获取出来形成map
Map<Long, String> usermap = userList.stream().collect(Collectors.toMap(User::getId, User::getUsername));
3.说明
  • toMap

我们先来看Stream流中toMap这个方法,他要求的是一个Function keyMapper接口

方法名 说明
public static Collector toMap(Function keyMapper,Function valueMapper) 把元素收集到Map集合中
  • Function接口

    Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值

    T是传递参数,R是返回值

方法名 说明
R apply(T t) 将此函数应用于给定的参数
  • 举例复习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class FunctionDemo {
public static void main(String[] args) {
convert("100",s -> Integer.parseInt(s));
convert("100",Integer::parseInt);
//用到的是引用类中的方法,parseInt是静态方法。所有参数全部传给parseInt
}

//定义一个方法,把一个字符串转换int类型,在控制台输出
private static void convert(String s, Function<String,Integer> fun) {
// Integer i = fun.apply(s);
int i = fun.apply(s);
System.out.println(i);
}

}
  • 引用

而对于User::getId显然用到的是,引用中的引用类的实例方法,其实就是引用类中的成员方法,对于这个方法的参数,我们有以下总结** Lambda表达式被类的实例方法替代的时候,第一个参数作为调用者,后面的参数全部传递给该方法作为参数**

1
2
3
4
List<User> userList = accountService.getUserList( userIds);

Map<Long, String> usermap = userList.stream().collect(Collectors.toMap(User::getId, User::getUsername)

1
2
3
4
public Long getId() 
{
return id;
}

根据stream流默认参数传递的是userList中的元素User实例,可以判断出这个调用者的参数是User user = new User();中的user(这只是一个形参,也可以是其它名字,),因此User::getId不做引用应该表达成user -> user.gerId,对应的mapper接口应该是这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FunctionDemo {
public static void main(String[] args) {
convert(User::getId);
convert(user -> user.gerId);
convert(User user ->
{
return user.getId
})

}
private static void convert(Function<User> fun) {
int i = fun.apply();
}
}