提高生产力!这10个Lambda表达式必须掌握,开辟服从嘎嘎上升! ...

打印 上一主题 下一主题

主题 909|帖子 909|积分 2727

在Java8及更高版本中,Lambda表达式的引入极大地提拔了编程的简洁性和服从。本文将围绕十个关键场景,展示Lambda如何助力提拔开辟服从,让代码更加精粹且易于理解。
聚集遍历

传统的for-each循环对聚集进行遍历固然直观,但在处置惩罚大量数据时显得冗长。比方:
  1. List<String> list = Arrays.asList("a", "b", "c");
  2. for (String s : list) {
  3.     System.out.println(s);
  4. }
复制代码
使用Lambda表达式后,代码变得更加紧凑:
  1. list.forEach(System.out::println);
复制代码
聚集排序

在从前我们对聚集中的元素进行排序时,必要实现Comparable接口,或者使用Comparator比较器,在其中定义排序规则。
  1. Collections.sort(list, new Comparator<String>() {
  2.     @Override
  3.     public int compare(String s1, String s2) {
  4.         return s1.length() - s2.length();
  5.     }
  6. });
复制代码
使用Lambda可以进行简化:
  1. List<String> sortedList = list.sort(Comparator.comparingInt(String::length));
  2. // 或者
  3. Collections.sort(list, (s1, s2) -> s1.length() - s2.length());
  4. // 或者
  5. Collections.sort(list, Comparator.comparingInt(String::length));
复制代码
聚集过滤

以往的过滤操作以往必要编写繁琐的条件判断。
  1. List<String> filterList = new ArrayList<>();
  2. for (String s : list){
  3.         if (s.length() >= 4){
  4.                 filterList.add(s);
  5.         }
  6. }
复制代码
使用Lambda可以进行简化:
  1. List<String> filterList = list.stream().filter(e -> e.length() >= 4).collect(Collectors.toList());
复制代码
关于Stream的使用方法请参考:提高Java开辟生产力,我选Stream,真香啊
映射操作

如以下操作,将一个聚集变成另外一个聚集
  1. List<String> upperCaseList = new ArrayList<>();
  2. for (String str : words) {
  3.     upperCaseList.add(str.toUpperCase());
  4. }
复制代码
而Lambda表达式可用于将聚集中的元素直接转换成新的情势:
  1. List<String> upperList = list.stream().map(e -> e.toUpperCase()).collect(Collectors.toList());
  2.                 upperList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
  3.                
  4.                 List<Integer> lengthList = list.stream().map(e -> e.length()).collect(Collectors.toList());
  5.                 lengthList = list.stream().map(String::length).collect(Collectors.toList());
复制代码
规约操作

规约操作,即对一个聚集中的元素进行求和,求均匀数等
  1. int sum = 0;
  2. for (int num : numbers) {
  3.     sum += num;
  4. }
复制代码
使用Lambda简化
  1. int sum = numbers.stream().mapToInt(Integer::intValue).sum();
  2. int sum = numbers.stream().reduce(0, (n1, n2) -> n1 + n2);
  3. int sum = numbers.stream().reduce(0, Integr::sum);
  4. List<Person> peoples = new ArrayList<>();
  5. int ages = peoples.stream().mapToInt(Person::getAge).sum();
复制代码
关于Stream的使用方法请参考:提高Java开辟生产力,我选Stream,真香啊
分组操作

对一个聚集基于特定规则对聚集进行分组,即将List转换为Map
  1. List<Person> personList = new ArrayList<>();
  2. Map<String, List<Person>> groupMap = new HashMap<>();
  3. for (Person person : personList) {
  4.     Integer age = person.getAge();
  5.     if (!groupMap.containsKey(age)) {
  6.         groupMap.put(age, new ArrayList<>());
  7.     }
  8.     groupMap.get(age).add(person);
  9. }
复制代码
使用Lambda简化:
  1. Map<String, List<Person>> groupMap = words.stream()
  2.     .collect(Collectors.groupingBy(Person::age));
复制代码
还有另外一种List转换为Map:
  1. List<Person> personList = new ArrayList<>();
  2. Map<Long, Person> personMap = new HashMap<>();
  3. for (Person person : personList) {
  4.    personMap.put(person.getId(), person);
  5. }
复制代码
使用Lambda简化:
  1. Map<String, Person> groupMap = words.stream()
  2.     .collect(Collectors.toMap(Person::id, Function.identity(), (e1, e2) -> e1));
复制代码
关于Stream的使用方法请参考:提高Java开辟生产力,我选Stream,真香啊
使用函数式接口

现在有一个函数式接口:
  1. @FunctionalInterface
  2. interface MyInterface{
  3.         void doSomething(String s);
  4. }
复制代码
常规做法在使用函数式接口时:
  1. MyInterface myInterface = new MyInterface() {
  2.         @Override
  3.         public void doSomething(String s) {
  4.                 System.out.println(s);
  5.         }
  6. };
  7. myInterface.doSomething("I am 码农Academy");
复制代码
使用Lamba进行优化:
  1. MyInterface myInterface = s -> System.out.println(s);
  2. myInterface.doSomething("I am 码农Academy");
复制代码
线程创建

以往创建线程的方式:
  1. Thread thread = new Thread(new Runnable() {
  2.     @Override
  3.     public void run() {
  4.         System.out.println("Hello, 码农Academy!");
  5.     }
  6. });
复制代码
使用Lambda简化后:
  1. Thread thread = new Thread(() -> System.out.println("Hello, 码农Academy!"));
  2. // 或者使用线程池方式
  3. ExecutorService executor = Executors.newFixedThreadPool(5); executor.execute(() -> longRunningTask());
复制代码
Optional

Optional可以避免空指针异常。
  1. Optional<String> optional = ...;
  2. if (optional.isPresent()) {
  3.     String value = optional.get();
  4.     // 处理value
  5. }
复制代码
使用Lambda简化:
  1. Optional<String> optional = ...;
  2. optional.ifPresent(value -> handleValue(value));
复制代码
关于使用Optional办理空指针的用法,可以参考:聊一聊日常开辟中如何避免那无处不在的让人头疼的NullPointerException
Stream的流水操作

在处置惩罚业务时,我们必要对一个聚集进行一系列的操作时,比如如下:
`
  1. List<Integer> result = new ArrayList<>();
  2. for (String str : list) {
  3.     if (str.matches("\\d+")) {
  4.         result.add(Integer.parseInt(str));
  5.     }
  6. }
复制代码
使用Stream API与Lambda结合,实现链式操作,使代码更清晰易读:
  1. List<Integer> result = list.stream()
  2.     .filter(str -> str.matches("\\d+"))
  3.     .map(Integer::parseInt)
  4.     .collect(Collectors.toList());
复制代码
比如我们使用Lambda结合Stream实现一个去重操作:
  1. /**
  2.      * 根据学生姓名查询除重复元素
  3.      * @param students
  4.      */
  5.     private static void repeatStudentsTest(List<Student> students){
  6.         // list 对应的 Stream
  7.       List<String> repeatStudents =   students.stream()
  8.               // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
  9.                 .collect(Collectors.toMap(e -> e.getName(), e -> 1, Integer::sum))
  10.               // 所有 entry 对应的 Stream
  11.                 .entrySet().stream()
  12.               // 过滤出元素出现次数大于 1 的 entry(过滤出来的是重复的,若这里条件是等于,即可达到去重的目的)
  13.                 .filter(entry -> entry.getValue()>1)
  14.             // 获得 entry 的键(重复元素)对应的 Stream
  15.                 .map(entry -> entry.getKey())
  16.               // 转化为 List
  17.                 .collect(Collectors.toList());
  18.         repeatStudents.forEach(repeatStudent -> {
  19.             System.out.println(repeatStudent);
  20.         });
  21.     }
复制代码
Lambda的断点调试

关于使用Idea开辟式,从前对代码断点时确实无法进入到lamda表达式内里,但是随着Idea的升级,已经办理了这个问题,可以在Lambda表达式的内部进行断点


Lambda易读

有人可能会认为Lambda表达式的代码阅读起来有些吃力,固然也是可以理解,其主要缘故原由有如下几个方面:

  • 匿名性:Lambda表达式本质上是匿名函数,没有显式的方法名称,因此,初次接触或不认识其语法的读者可能难以快速理解其意图,尤其是在较复杂的上下文中。
  • 简洁性:Lambda表达式的目的是为了简化代码,它往往非常紧凑,可能会把原本分散在多个行或方法中的逻辑压缩到一行甚至一部分内。这样的代码密度可能导致理解上的难度,特别是当逻辑较为复杂时。
  • 抽象层次:Lambda表达式常与函数式接口一起使用,这意味着理解Lambda表达式必要知道它所对应接口的行为约定。如果读者不了解接口的具体功能,那么Lambda表达式就可能变得难以解读。
  • 函数式编程范式:对于习惯于下令式编程风格的开辟者来说,函数式编程的头脑方式和Lambda表达式的使用可能必要肯定适应期。尤其是涉及到闭包、高阶函数等概念时,如果不认识这些概念,理解Lambda表达式的逻辑会更加困难。
  • 依赖上下文:Lambda表达式经常用于流(Stream)操作、事件监听、回调函数等场景,其含义高度依赖于上下文环境。在缺少充分表明或文档的情况下,阅读者可能必要花费更多精力去推理其作用。
但是,随着Java 8以来函数式编程特性的遍及,越来越多的Coder们开始接受并纯熟使用Lambda表达式。适当的代码构造、表明和遵循良好的编程规范有助于低落Lambda表达式带来的阅读障碍。并且随着经验的增长和技术背景的丰富,我们会渐渐认识到Lambda表达式的长处,即它可以增强代码的可读性和简洁性,尤其在处置惩罚数据流和进行函数组合时。
总结

纯熟运用Lambda表达式能够显著提拔代码质量与开辟服从,使得代码逻辑更加简明扼要,同时也增强了程序的可读性与维护性。不断学习和实践这些技巧,你的开辟服从必将迎来质的飞跃。并且Lambda与Stream一起使用才能发挥他们最大的长处。关于Stream的使用方法请参考:提高Java开辟生产力,我选Stream,真香啊
本文已收录于我的个人博客:码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中间件、架构设计、面试题、程序员攻略等

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

圆咕噜咕噜

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表