Lambda表达式
Lambda表达式
前言
在日常开发中,我们很多时候需要用到Java 8
的Lambda
表达式,它允许把函数作为一个方法的参数,让我们的代码更优雅,更简洁。以下为常用的表达式写法。
.collect()用来起保存作用的函数
List转Map
Collectors.toMap可以把一个List数组转成一个Map,代码如下
1 | public class TestLanbda { |
使用toMap()
函数之后,返回的就是一个Map
了,自然会需要key
和value
第一个参数用来生成
key
值
第二个参数用来生成value
值
第三个参数用在key值冲突的情况下:如果新元素产生的key在Map中已经出现过了,第三个参数就会定义解决的方法。
在.collect(Collectors.toMap(Person::getId, v -> v, (a,b) -> a)):
第一个参数:Person:getId表示选择Person的getId作为map的key值;
第二个参数:v -> v表示选择将原来的对象作为Map的value值
第三个参数:(a,b) -> a中,如果a与b的key值相同,选择a作为那个key所对应的value值。
类似的,还有Collectors.toList()、Collectors.toSet(),表示把对应的流转化为List或Set。
Filter()过滤
从数组集合中,过滤掉不符合条件的元素,留下符合条件的元素。
1 | List<UserInfo> userInfoList = new ArrayList<>(); |
forEach()循环
1 | /** |
groupingBy分组
提到分组,相信大家都会想到SQL的group by。我们经常需要一个List做分组操作。比如,按城市分组用户。在Java8之前,是这么实现的:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15List<UserInfo> userInfoList = new ArrayList<>();
userInfoList.add(new UserInfo(1L, "采蘑菇的小姑娘",18, "沈阳"));
userInfoList.add(new UserInfo(2L, "程序员男孩", 22, "深圳"));
userInfoList.add(new UserInfo(2L, "捡瓶子的小姑娘", 20, "沈阳"));
Map<String, List<UserInfo>> result = new HashMap<>();
for (UserInfo userInfo : UserInfoList) {
String city = userInfo.getCity();
List<UserInfo> userInfos = result.get(city);
if (userInfos == null) {
userInfos = new ArrayList<>();
result.put(city, userInfos);
}
userInfos.add(userInfo);
}
而使用Java8的groupingby
分组器,则很简单:1
2Map<String,List<UserInfo>> result = userInfoList.stream()
.collect(Collectors.groupingBy(UserInfo::getCity))
sorted + Comparator排序
在实际编写代码中,排序的需求比较多,使用sorted+Comparator排序可以简化很多1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28List<UserInfo> userInfoList = new ArrayList<>();
userInfoList.add(new UserInfo(1L, "采蘑菇的小姑娘",18));
userInfoList.add(new UserInfo(2L, "程序员男孩", 22));
userInfoList.add(new UserInfo(2L, "捡瓶子的小姑娘", 20));
/**
* sorted + Comparator.comparing 排序列表
*/
userInfoList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge)).collect(Collectors.toList());
System.out.println("开始升序排序")
userInfo.forEach(a -> System.out.println(a.toString()));
/**
* 如果想要降序排序,可以使用加reversed()
*/
System.out.println("开始降序排序")
userInfoList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge).reversed()).collect(Collectors.toList());
userInfo.forEach(a -> System.out.println(a.toString()));
// 运行结果
开始升序排序
userInfo{userId = 1, userName = '采蘑菇的小姑娘', age = 18}
userInfo{userId = 3, userName = '捡瓶子的小姑娘', age = 20}
userInfo{userId = 2, userName = '程序员男孩', age = 22}
开始降序排序
userInfo{userId = 2, userName = '程序员男孩', age = 22}
userInfo{userId = 3, userName = '捡瓶子的小姑娘', age = 20}
userInfo{userId = 1, userName = '采蘑菇的小姑娘', age = 18}
distinct()去重
1 | List<String> list = Arrays.asList("A","B","F","A","C"); |
findFirst()返回第一个
1 | List<String> list = Arrays.asList("A","B","F","A","C"); |
anyMatch()和allMatch()匹配
anyMatch()检查流是否包含至少一个满足要求1
2
3
4
5Stream<String> stream = Stream.of("A","B","C","D");
boolean match = stream.anyMatch(s -> s.contains("C"));
System.out.println(match);
//输出
true
allMatch()检查流是否所有都满足1
2
3
4
5Stream<String> stream = Stream.of("A","B","C","D");
boolean match = stream.anyMatch(s -> s.length() == 1);
System.out.println(match);
//输出
true
常用函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
函数式接口可以被隐式转换为Lambda
表达式Lambda
表达式和方法引用(实际上也可认为是Lambda
表达式)上
常见的函数式接口
Function<T, R>
(转换型):接收一个输入参数,返回一个结果Comsumer<T>
(消费型):接收一个输入参数,并且无返回操作Predicate<T>
(判断型):接收一个输入参数,并且返回布尔值结果Supplier<T>
(供给型):无参数,无返回结果