前言
闲来无事,整理一下工作中常用的Java8 中常用的Lambda 表达式,方便自己查阅,如果能帮助到一些人那就再好不过了!
Lambda表达式,可以使我们的代码更加简洁、优雅,但也不要滥用,因为在一定程度上复杂的Lambda表达式反而降低了代码的可阅读性,所以说各位还是要灵活运用。
基础数据准备
为了方便演示,准备了一些基础数据:
List<BaseInfo> infoList = new ArrayList<>();
infoList.add(new BaseInfo(10L, "小明", "北京"));
infoList.add(new BaseInfo(11L, "小葱", "天津"));
infoList.add(new BaseInfo(10L, "小明", "济南"));
infoList.add(new BaseInfo(9L, "小刚", "青岛"));
infoList.add(new BaseInfo(18L, "小红", "海口"));
infoList.add(new BaseInfo(33L, "小李", "上海"));
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
1. List 转 Map
Map<Long,BaseInfo> infoMap = infoList.stream().collect(Collectors.toMap(BaseInfo::getId,item ->item));
对于我们上面造的数据,上述执行结果会报错:java.lang.IllegalStateException: Duplicate key 这是因为第一条和第三条出现了重复健:10,这时候我们就需要下面的方式:
Map<Long, BaseInfo> nonRepeatInfoMap = infoList.stream().collect(Collectors.toMap(BaseInfo::getId, item -> item, (key1, key2) -> key1));
处理重复健问题 加 (key1,key2) -> key1 表示存在重复健时取key1 ,当然也可以 (key1,key2) -> key1 表示存在重复健时取key2。
从上面的输出结果我们发现重复健的问题解决了,但是输出的结果却没有按照我们添加进list的顺序进行输出(因为通过源码可以发现Collectors.toMap()源码发现其输出的Map是HashMap,而HashMap不是按顺序存的),在某些场景中我们是需要按照顺序输出的;所以也就有了下面的方法:
Map<Long, BaseInfo> orderInfoMap = infoList.stream().collect(Collectors.toMap(BaseInfo::getId, item -> item, (key1, key2) -> key1, LinkedHashMap::new));
这里稍微解释一下为什么列举了三种:因为不同的需求场景的需求,比如报错的第一种,某种场景下转Map的时候就是需要唯一健,这是出现报错我们更能发现问题,让我们去检查数据,因此各位根据自己的需求去选择用哪种方式。
2. groupingBy 分组
Map<Long, List<BaseInfo>> groupMap = infoList.stream().collect(Collectors.groupingBy(BaseInfo::getId));
同样上述的方法输出分组为乱序的,其原因同样也是:Collectors.groupingBy()输出为HashMap,因此如果对顺序有要求的话可以使用下面的方式:
Map<Long, List<BaseInfo>> orderGroupMap = infoList.stream().collect(Collectors.groupingBy(BaseInfo::getId, LinkedHashMap::new, Collectors.toList()));
3. map 转换
获取对象中某一个属性的值构成List:
List<String> nameList = infoList.stream().map(BaseInfo::getName).collect(Collectors.toList());
当然也可以做元素的转换(例子方便演示,还请各位不要纠结Long 转Integer的问题):
List<Integer> integerList = infoList.stream().map(BaseInfo::getId).map(item -> Integer.parseInt(item.toString())).collect(Collectors.toList());
4.distinct 去重
整体去重:
List<BaseInfo> distinctEntityList = infoList.stream().distinct().collect(Collectors.toList());
指定属性去重:
List<BaseInfo> distinctAppointList = infoList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item -> item.getName()))), ArrayList::new));
取对象中某一属性去重后数据:
List<String> distinctNameList = infoList.stream().map(BaseInfo::getName).distinct().collect(Collectors.toList());
5. foreach 遍历
list 遍历:
infoList.forEach(item -> {
System.out.println(item.getName());
});
infoList.forEach(item -> System.out.println(item.getName()));
map 遍历:
orderInfoMap.forEach((k, v) -> {
//可以进行多个操作
System.out.println(k + "-" + v);
});
6.filter 过滤
// 获取 id大于15的数据
List<BaseInfo> filterList = infoList.stream().filter(item -> item.getId() > 15L).collect(Collectors.toList());
7. sorted + comparator 排序
//(1) 升序
List<BaseInfo> sortedList = infoList.stream().sorted(Comparator.comparing(BaseInfo::getId)).collect(Collectors.toList());
//(2) 降序(reversed)
List<BaseInfo> reversedSortedList = infoList.stream().sorted(Comparator.comparing(BaseInfo::getId).reversed()).collect(Collectors.toList());
8. 匹配 anyMatch & allMatch
//1. anyMatch 是否至少匹配一个元素
boolean match = list.stream().anyMatch(item -> item.contains("A"));
// true
//2. allMatch 匹配所有元素
boolean allMatch = list.stream().allMatch(item -> item.contains("B"));
// false
9. 统计 max & min & findFirst & count & sum
// (1) max
Optional<BaseInfo> max = infoList.stream().max(Comparator.comparing(BaseInfo::getId));
max.ifPresent(item -> System.out.println(item.getName()));
//(2) min
Optional<BaseInfo> min = infoList.stream().min(Comparator.comparing(BaseInfo::getId));
min.ifPresent(item -> System.out.println(item.getName()));
//(3) count
long count = infoList.stream().filter(item -> item.getId() > 15L).count();
//(4) sum
Long sum = infoList.stream().mapToLong(BaseInfo::getId).sum();
//(5) findFirst
Optional<BaseInfo> firstInfo = infoList.stream().findFirst();
infoList.stream().findFirst().ifPresent(item -> System.out.println(item.getAddress()));
总结
以上只是简单的列举了Java 8 中 Lambda的部分简单用法,希望能在日常的开发中助你一臂之力!!!