[JAVA] 简单聊聊工作中常用的JavaLambda表达式

2427 6
Honkers 2022-11-6 11:29:58 | 显示全部楼层 |阅读模式
目录

    前言1. list转map2. filter()过滤3. foreach遍历4. groupingBy分组5. sorted+Comparator 排序6.distinct去重7. findFirst 返回第一个8. anyMatch是否至少匹配一个元素9. allMatch 匹配所有元素10. map转换11. Reduce12. peek 打印个日志13. Max,Min最大最小14. count统计15. 常用函数式接口


前言

日常开发中,我们很多时候需要用到Java 8的Lambda表达式,它允许把函数作为一个方法的参数,让我们的代码更优雅、更简洁。所以整理了一波工作中,我常用的,有哪些Lambda表达式。看完一定会有帮助的。

1. list转map

工作中,我们经常遇到list转map的案例。Collectors.toMap就可以把一个list数组转成一个Map。代码如下:
publicclassTestLambda{publicstaticvoidmain(String[]args){List<UserInfo>userInfoList=newArrayList<>();userInfoList.add(newUserInfo(1L,"捡田螺的小男孩",18));userInfoList.add(newUserInfo(2L,"程序员田螺",27));userInfoList.add(newUserInfo(2L,"捡瓶子的小男孩",26));/***list转map*使用Collectors.toMap的时候,如果有可以重复会报错,所以需要加(k1,k2)->k1*(k1,k2)->k1表示,如果有重复的key,则保留第一个,舍弃第二个*/Map<Long,UserInfo>userInfoMap=userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId,userInfo->userInfo,(k1,k2)->k1));userInfoMap.values().forEach(a->System.out.println(a.getUserName()));}}运行结果
捡田螺的小男孩
程序员田螺
类似的,还有Collectors.toList()、Collectors.toSet(),表示把对应的流转化为list或者Set。

2. filter()过滤

从数组集合中,过滤掉不符合条件的元素,留下符合条件的元素。
  1. List<UserInfo>userInfoList=newArrayList<>();
  2. userInfoList.add(newUserInfo(1L,"捡田螺的小男孩",18));
  3. userInfoList.add(newUserInfo(2L,"程序员田螺",27));
  4. userInfoList.add(newUserInfo(3L,"捡瓶子的小男孩",26));
  5. /**
  6. *filter过滤,留下超过18岁的用户
  7. */
  8. List<UserInfo>userInfoResultList=userInfoList.stream().filter(user->user.getAge()>18).collect(Collectors.toList());
  9. userInfoResultList.forEach(a->System.out.println(a.getUserName()));
复制代码
运行结果
程序员田螺
捡瓶子的小男孩

3. foreach遍历

foreach 遍历list,遍历map,真的很丝滑。
  1. /**
  2. *forEach遍历集合List列表
  3. */
  4. List<String>userNameList=Arrays.asList("捡田螺的小男孩","程序员田螺","捡瓶子的小男孩");
  5. userNameList.forEach(System.out::println);
  6. HashMap<String,String>hashMap=newHashMap<>();
  7. hashMap.put("公众号","捡田螺的小男孩");
  8. hashMap.put("职业","程序员田螺");
  9. hashMap.put("昵称","捡瓶子的小男孩");
  10. /**
  11. *forEach遍历集合Map
  12. */
  13. hashMap.forEach((k,v)->System.out.println(k+":\t"+v));
复制代码
运行结果
捡田螺的小男孩
程序员田螺
捡瓶子的小男孩
职业: 程序员田螺
公众号: 捡田螺的小男孩
昵称: 捡瓶子的小男孩

4. groupingBy分组

提到分组,相信大家都会想起SQL的group by。我们经常需要一个List做分组操作。比如,按城市分组用户。在Java8之前,是这么实现的:
  1. List<UserInfo>originUserInfoList=newArrayList<>();
  2. originUserInfoList.add(newUserInfo(1L,"捡田螺的小男孩",18,"深圳"));
  3. originUserInfoList.add(newUserInfo(3L,"捡瓶子的小男孩",26,"湛江"));
  4. originUserInfoList.add(newUserInfo(2L,"程序员田螺",27,"深圳"));
  5. Map<String,List<UserInfo>>result=newHashMap<>();
  6. for(UserInfouserInfo:originUserInfoList){
  7. Stringcity=userInfo.getCity();
  8. List<UserInfo>userInfos=result.get(city);
  9. if(userInfos==null){
  10. userInfos=newArrayList<>();
  11. result.put(city,userInfos);
  12. }
  13. userInfos.add(userInfo);
  14. }
复制代码
而使用Java8的groupingBy分组器,清爽无比:
  1. Map<String,List<UserInfo>>result=originUserInfoList.stream()
  2. .collect(Collectors.groupingBy(UserInfo::getCity));
复制代码
5. sorted+Comparator 排序

工作中,排序的需求比较多,使用sorted+Comparator排序,真的很香。
  1. List<UserInfo>userInfoList=newArrayList<>();
  2. userInfoList.add(newUserInfo(1L,"捡田螺的小男孩",18));
  3. userInfoList.add(newUserInfo(3L,"捡瓶子的小男孩",26));
  4. userInfoList.add(newUserInfo(2L,"程序员田螺",27));
  5. /**
  6. *sorted+Comparator.comparing排序列表,
  7. */
  8. userInfoList=userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge)).collect(Collectors.toList());
  9. userInfoList.forEach(a->System.out.println(a.toString()));
  10. System.out.println("开始降序排序");
  11. /**
  12. *如果想降序排序,则可以使用加reversed()
  13. */
  14. userInfoList=userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge).reversed()).collect(Collectors.toList());
  15. userInfoList.forEach(a->System.out.println(a.toString()));
复制代码
运行结果
UserInfo{userId=1, userName='捡田螺的小男孩', age=18}
UserInfo{userId=3, userName='捡瓶子的小男孩', age=26}
UserInfo{userId=2, userName='程序员田螺', age=27}
开始降序排序
UserInfo{userId=2, userName='程序员田螺', age=27}
UserInfo{userId=3, userName='捡瓶子的小男孩', age=26}
UserInfo{userId=1, userName='捡田螺的小男孩', age=18}

6.distinct去重

distinct可以去除重复的元素:
  1. List<String>list=Arrays.asList("A","B","F","A","C");
  2. List<String>temp=list.stream().distinct().collect(Collectors.toList());
  3. temp.forEach(System.out::println);
复制代码
7. findFirst 返回第一个

findFirst 很多业务场景,我们只需要返回集合的第一个元素即可:
  1. List<String>list=Arrays.asList("A","B","F","A","C");
  2. list.stream().findFirst().ifPresent(System.out::println);
复制代码
8. anyMatch是否至少匹配一个元素

anyMatch 检查流是否包含至少一个满足给定谓词的元素。
  1. Stream<String>stream=Stream.of("A","B","C","D");
  2. booleanmatch=stream.anyMatch(s->s.contains("C"));
  3. System.out.println(match);
复制代码
输出
true

9. allMatch 匹配所有元素

allMatch 检查流是否所有都满足给定谓词的元素。
  1. Stream<String>stream=Stream.of("A","B","C","D");
  2. booleanmatch=stream.allMatch(s->s.contains("C"));
  3. System.out.println(match);
复制代码
输出
false

10. map转换

map方法可以帮我们做元素转换,比如一个元素所有字母转化为大写,又或者把获取一个元素对象的某个属性,demo如下:
  1. List<String>list=Arrays.asList("jay","tianluo");
  2. //转化为大写
  3. List<String>upperCaselist=list.stream().map(String::toUpperCase).collect(Collectors.toList());
  4. upperCaselist.forEach(System.out::println);
复制代码
11. Reduce

Reduce可以合并流的元素,并生成一个值
  1. intsum=Stream.of(1,2,3,4).reduce(0,(a,b)->a+b);
  2. System.out.println(sum);
复制代码
12. peek 打印个日志

peek()方法是一个中间Stream操作,有时候我们可以使用peek来打印日志。
  1. List<String>result=Stream.of("程序员田螺","捡田螺的小男孩","捡瓶子的小男孩")
  2. .filter(a->a.contains("田螺"))
  3. .peek(a->System.out.println("关注公众号:"+a)).collect(Collectors.toList());
  4. System.out.println(result);
复制代码
运行结果
关注公众号:程序员田螺
关注公众号:捡田螺的小男孩
[程序员田螺, 捡田螺的小男孩]

13. Max,Min最大最小

使用lambda流求最大,最小值,非常方便。
  1. List<UserInfo>userInfoList=newArrayList<>();
  2. userInfoList.add(newUserInfo(1L,"捡田螺的小男孩",18));
  3. userInfoList.add(newUserInfo(3L,"捡瓶子的小男孩",26));
  4. userInfoList.add(newUserInfo(2L,"程序员田螺",27));
  5. Optional<UserInfo>maxAgeUserInfoOpt=userInfoList.stream().max(Comparator.comparing(UserInfo::getAge));
  6. maxAgeUserInfoOpt.ifPresent(userInfo->System.ou.println("maxage user:"+userInfo));
  7. Optional<UserInfo>minAgeUserInfoOpt=userInfoList.stream().min(Comparator.comparing(UserInfo::getAge));
  8. minAgeUserInfoOpt.ifPresent(userInfo->System.out.println("minage user:"+userInfo));
复制代码
运行结果
max age user:UserInfo{userId=2, userName='程序员田螺', age=27}
min age user:UserInfo{userId=1, userName='捡田螺的小男孩', age=18}

14. count统计

一般count()表示获取流数据元素总数。
  1. List<UserInfo>userInfoList=newArrayList<>();
  2. userInfoList.add(newUserInfo(1L,"捡田螺的小男孩",18));
  3. userInfoList.add(newUserInfo(3L,"捡瓶子的小男孩",26));
  4. userInfoList.add(newUserInfo(2L,"程序员田螺",27));
  5. longcount=userInfoList.stream().filter(user->user.getAge()>18).count();
  6. System.out.println("大于18岁的用户:"+count);
复制代码
输出
大于18岁的用户:2

15. 常用函数式接口

其实lambda离不开函数式接口,我们来看下JDK8常用的几个函数式接口:
    Function<T, R>(转换型): 接受一个输入参数,返回一个结果Consumer<T> (消费型): 接收一个输入参数,并且无返回操作Predicate<T> (判断型): 接收一个输入参数,并且返回布尔值结果Supplier<T> (供给型): 无参数,返回结果
Function<T, R> 是一个功能转换型的接口,可以把将一种类型的数据转化为另外一种类型的数据
  1. privatevoidtestFunction(){
  2. //获取每个字符串的长度,并且返回
  3. Function<String,Integer>function=String::length;
  4. Stream<String>stream=Stream.of("程序员田螺","捡田螺的小男孩","捡瓶子的小男孩");
  5. Stream<Integer>resultStream=stream.map(function);
  6. resultStream.forEach(System.out::println);
  7. }
复制代码
Consumer<T>是一个消费性接口,通过传入参数,并且无返回的操作
  1. privatevoidtestComsumer(){
  2. //获取每个字符串的长度,并且返回
  3. Consumer<String>comsumer=System.out::println;
  4. Stream<String>stream=Stream.of("程序员田螺","捡田螺的小男孩","捡瓶子的小男孩");
  5. stream.forEach(comsumer);
  6. }
复制代码
Predicate<T>是一个判断型接口,并且返回布尔值结果.
  1. privatevoidtestPredicate(){
  2. //获取每个字符串的长度,并且返回
  3. Predicate<Integer>predicate=a->a>18;
  4. UserInfouserInfo=newUserInfo(2L,"程序员田螺",27);
  5. System.out.println(predicate.test(userInfo.getAge()));
  6. }
复制代码
Supplier<T>是一个供给型接口,无参数,有返回结果。
  1. privatevoidtestSupplier(){
  2. Supplier<Integer>supplier=()->Integer.valueOf("666");
  3. System.out.println(supplier.get());
  4. }
复制代码
这几个函数在日常开发中,也是可以灵活应用的,比如我们DAO操作完数据库,是会有个result的整型结果返回。我们就可以用Supplier<T>来统一判断是否操作成功。如下:
  1. privatevoidsaveDb(Supplier<Integer>supplier){
  2. if(supplier.get()>0){
  3. System.out.println("插入数据库成功");
  4. }else{
  5. System.out.println("插入数据库失败");
  6. }
  7. }
  8. @Test
  9. publicvoidadd()throwsException{
  10. Coursecourse=newCourse();
  11. course.setCname("java");
  12. course.setUserId(100L);
  13. course.setCstatus("Normal");
  14. saveDb(()->courseMapper.insert(course));
  15. }
复制代码
到此这篇关于简单聊聊工作中常用的Java Lambda表达式的文章就介绍到这了,更多相关Java Lambda表达式内容请搜索中国红客联盟以前的文章或继续浏览下面的相关文章希望大家以后多多支持中国红客联盟!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4008
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行