码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 提高生产力!这10个Lambda表达式必须掌握,开发效率嘎嘎上升!


    在Java8及更高版本中,Lambda表达式的引入极大地提升了编程的简洁性和效率。本文将围绕十个关键场景,展示Lambda如何助力提升开发效率,让代码更加精炼且易于理解。

    集合遍历

    传统的for-each循环对集合进行遍历虽然直观,但在处理大量数据时显得冗长。例如:

    List list = Arrays.asList("a", "b", "c");
    for (String s : list) {
        System.out.println(s);
    }
    

    使用Lambda表达式后,代码变得更加紧凑:

    list.forEach(System.out::println);
    

    集合排序

    在以前我们对集合中的元素进行排序时,需要实现Comparable接口,或者使用Comparator比较器,在其中定义排序规则。

    Collections.sort(list, new Comparator() {
        @Override
        public int compare(String s1, String s2) {
            return s1.length() - s2.length();
        }
    });
    

    使用Lambda可以进行简化:

    List sortedList = list.sort(Comparator.comparingInt(String::length));
    
    // 或者
    Collections.sort(list, (s1, s2) -> s1.length() - s2.length());
    
    // 或者
    Collections.sort(list, Comparator.comparingInt(String::length));
    

    集合过滤

    以往的过滤操作以往需要编写繁琐的条件判断。

    List filterList = new ArrayList<>();
    for (String s : list){
    	if (s.length() >= 4){
    		filterList.add(s);
    	}
    }
    

    使用Lambda可以进行简化:

    List filterList = list.stream().filter(e -> e.length() >= 4).collect(Collectors.toList());
    

    关于Stream的使用方法请参考:提高Java开发生产力,我选Stream,真香啊

    映射操作

    如以下操作,将一个集合变成另外一个集合

    List upperCaseList = new ArrayList<>();
    for (String str : words) {
        upperCaseList.add(str.toUpperCase());
    }
    

    而Lambda表达式可用于将集合中的元素直接转换成新的形式:

    List upperList = list.stream().map(e -> e.toUpperCase()).collect(Collectors.toList());
    		upperList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
    		
    		List lengthList = list.stream().map(e -> e.length()).collect(Collectors.toList());
    		lengthList = list.stream().map(String::length).collect(Collectors.toList());
    

    规约操作

    规约操作,即对一个集合中的元素进行求和,求平均数等

    int sum = 0;
    for (int num : numbers) {
        sum += num;
    }
    

    使用Lambda简化

    int sum = numbers.stream().mapToInt(Integer::intValue).sum();
    int sum = numbers.stream().reduce(0, (n1, n2) -> n1 + n2);
    int sum = numbers.stream().reduce(0, Integr::sum);
    
    List peoples = new ArrayList<>();
    int ages = peoples.stream().mapToInt(Person::getAge).sum();
    

    关于Stream的使用方法请参考:提高Java开发生产力,我选Stream,真香啊

    分组操作

    对一个集合基于特定规则对集合进行分组,即将List转换为Map>

    List personList = new ArrayList<>();
    Map> groupMap = new HashMap<>();
    for (Person person : personList) {
        Integer age = person.getAge();
        if (!groupMap.containsKey(age)) {
            groupMap.put(age, new ArrayList<>());
        }
        groupMap.get(age).add(person);
    }
    

    使用Lambda简化:

    Map> groupMap = words.stream()
        .collect(Collectors.groupingBy(Person::age));
    

    还有另外一种List转换为Map:

    List personList = new ArrayList<>();
    Map personMap = new HashMap<>();
    for (Person person : personList) {
       personMap.put(person.getId(), person);
    }
    

    使用Lambda简化:

    Map groupMap = words.stream()
        .collect(Collectors.toMap(Person::id, Function.identity(), (e1, e2) -> e1));
    

    关于Stream的使用方法请参考:提高Java开发生产力,我选Stream,真香啊

    使用函数式接口

    现在有一个函数式接口:

    @FunctionalInterface
    interface MyInterface{
    	void doSomething(String s);
    }
    

    常规做法在使用函数式接口时:

    MyInterface myInterface = new MyInterface() {
    	@Override
    	public void doSomething(String s) {
    		System.out.println(s);
    	}
    };
    
    myInterface.doSomething("I am 码农Academy");
    

    使用Lamba进行优化:

    MyInterface myInterface = s -> System.out.println(s);
    myInterface.doSomething("I am 码农Academy");
    

    线程创建

    以往创建线程的方式:

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello, 码农Academy!");
        }
    });
    

    使用Lambda简化后:

    Thread thread = new Thread(() -> System.out.println("Hello, 码农Academy!"));
    
    // 或者使用线程池方式
    ExecutorService executor = Executors.newFixedThreadPool(5); executor.execute(() -> longRunningTask());
    

    Optional

    Optional可以避免空指针异常。

    Optional optional = ...;
    if (optional.isPresent()) {
        String value = optional.get();
        // 处理value
    }
    

    使用Lambda简化:

    Optional optional = ...;
    optional.ifPresent(value -> handleValue(value));
    

    关于使用Optional解决空指针的用法,可以参考:聊一聊日常开发中如何避免那无处不在的让人头疼的NullPointerException

    Stream的流水操作

    在处理业务时,我们需要对一个集合进行一系列的操作时,比如如下:
    `

    List result = new ArrayList<>();
    for (String str : list) {
        if (str.matches("\\d+")) {
            result.add(Integer.parseInt(str));
        }
    }
    

    利用Stream API与Lambda结合,实现链式操作,使代码更清晰易读:

    List result = list.stream()
        .filter(str -> str.matches("\\d+"))
        .map(Integer::parseInt)
        .collect(Collectors.toList());
    

    比如我们使用Lambda结合Stream实现一个去重操作:

    /**
         * 根据学生姓名查询除重复元素
         * @param students
         */
        private static void repeatStudentsTest(List students){
            // list 对应的 Stream
          List repeatStudents =   students.stream()
                  // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
                    .collect(Collectors.toMap(e -> e.getName(), e -> 1, Integer::sum))
                  // 所有 entry 对应的 Stream
                    .entrySet().stream()
                  // 过滤出元素出现次数大于 1 的 entry(过滤出来的是重复的,若这里条件是等于,即可达到去重的目的)
                    .filter(entry -> entry.getValue()>1)
                // 获得 entry 的键(重复元素)对应的 Stream
                    .map(entry -> entry.getKey())
                  // 转化为 List
                    .collect(Collectors.toList());
    
            repeatStudents.forEach(repeatStudent -> {
                System.out.println(repeatStudent);
            });
        }
    

    Lambda的断点调试

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

    image.png

    image.png

    Lambda易读

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

    1. 匿名性:Lambda表达式本质上是匿名函数,没有显式的方法名称,因此,初次接触或不熟悉其语法的读者可能难以快速理解其意图,尤其是在较复杂的上下文中。

    2. 简洁性:Lambda表达式的目的是为了简化代码,它往往非常紧凑,可能会把原本分散在多个行或方法中的逻辑压缩到一行甚至一部分内。这样的代码密度可能导致理解上的难度,特别是当逻辑较为复杂时。

    3. 抽象层次:Lambda表达式常与函数式接口一起使用,这意味着理解Lambda表达式需要知道它所对应接口的行为约定。如果读者不了解接口的具体功能,那么Lambda表达式就可能变得难以解读。

    4. 函数式编程范式:对于习惯于命令式编程风格的开发者来说,函数式编程的思维方式和Lambda表达式的使用可能需要一定适应期。尤其是涉及到闭包、高阶函数等概念时,如果不熟悉这些概念,理解Lambda表达式的逻辑会更加困难。

    5. 依赖上下文:Lambda表达式经常用于流(Stream)操作、事件监听、回调函数等场景,其含义高度依赖于上下文环境。在缺少充分注释或文档的情况下,阅读者可能需要花费更多精力去推理其作用。

    但是,随着Java 8以来函数式编程特性的普及,越来越多的Coder们开始接受并熟练使用Lambda表达式。适当的代码组织、注释和遵循良好的编程规范有助于降低Lambda表达式带来的阅读障碍。并且随着经验的增长和技术背景的丰富,我们会逐渐认识到Lambda表达式的优点,即它可以增强代码的可读性和简洁性,尤其在处理数据流和进行函数组合时。

    总结

    熟练运用Lambda表达式能够显著提升代码质量与开发效率,使得代码逻辑更加简明扼要,同时也增强了程序的可读性与维护性。不断学习和实践这些技巧,你的开发效率必将迎来质的飞跃。并且Lambda与Stream一起使用才能发挥他们最大的优点。关于Stream的使用方法请参考:提高Java开发生产力,我选Stream,真香啊

    本文已收录于我的个人博客:码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中间件、架构设计、面试题、程序员攻略等

  • 相关阅读:
    设计模式(五)设计原则part2
    mac安装python虚拟环境
    网站整站优化-网站整站优化工具
    搭建自己的搜索引擎之三
    事务的四大特性
    C#Winform中打印预览时设置横向打印
    windows的软件修改图标
    阿里云 —— Windows下搭建“阿里云音视频通信RTC“(2)
    高级网络调试技巧:使用Charles Proxy捕获和修改HTTP/HTTPS请求
    【问题思考总结】如何求椭圆的切线?【过椭圆外一点】
  • 原文地址:https://www.cnblogs.com/coderacademy/p/18111975
    • 最新文章
    • 攻防演习之三天拿下官网站群
      数据安全治理学习——前期安全规划和安全管理体系建设
      企业安全 | 企业内一次钓鱼演练准备过程
      内网渗透测试 | Kerberos协议及其部分攻击手法
      0day的产生 | 不懂代码的"代码审计"
      安装scrcpy-client模块av模块异常,环境问题解决方案
      leetcode hot100【LeetCode 279. 完全平方数】java实现
      OpenWrt下安装Mosquitto
      AnatoMask论文汇总
      【AI日记】24.11.01 LangChain、openai api和github copilot
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
    正则表达式工具 cron表达式工具 密码生成工具

    京公网安备 11010502049817号