本文配套教学视频:B站观看地址

在本号之前写过的一些文章中,笔者使用了lambda表达式语法,一些读者反映说代码看不懂。本以为java 13都已经出了,java 8中最重要特性lambda表达式大家应该都掌握了,实际上还是存在大量的程序员没有使用java8,还有的使用了java8也不会使用lambda表达式。

Lambda表达式是Java 8最流行最常用的功能特性。它将函数式编程概念引入Java,函数式编程的好处在于可以帮助我们节省大量的代码,非常方便易用,能够大幅度的提高我们的编码效率。在本文中,我们将介绍lambda表达式是什么,并将传统的java代码写法转换为lambda表达式写法,大家可以通过示例了解lambda表达式都对传统代码做了哪些简化。

本文配套教学视频:B站观看地址

一、接口定义

首先,我们要明白lambda表达式在表达什么?答案就是lambda表达式表达接口函数的实现,所以我们有必要做一下准备工作。在传统的开发方式下,我们不习惯将代码块传递给函数。我们所有的行为定义代码都封装在方法体内,并通过对象引用执行,就像使用下面的代码一样:

public class LambdaDemo {
//函数定义
public void printSomething(String something) {
System.out.println(something);
}
//通过创建对象调用函数
public static void main(String[] args) {
LambdaDemo demo = new LambdaDemo();
String something = "I am learning Lambda";
demo.printSomething(something);
}
}

大家应该对上面的代码的开发方式不感到陌生,这是经典OOP的实现样式。下面我们对上面的代码做一个修改,创建一个功能接口,并对该接口定义抽象方法。


public class LambdaDemo {
//抽象功能接口
interface Printer {
void print(String val);
}
//通过参数传递功能接口
public void printSomething(String something, Printer printer) {
printer.print(something);
}
}

本文配套教学视频:B站观看地址

二、传统的接口函数实现方式

在上述实现中,Printer接口负责打印行为,可以是控制台打印,也可以是其他的打印行为。方法printSomething不再定义行为,而是执行Printer定义的行为,这样的设计更加灵活。代码如下:


public static void main(String[] args) {
LambdaDemo demo = new LambdaDemo();
String something = "I am using a Functional interface";
//实现Printer接口
Printer printer = new Printer() {
@Override
public void print(String val) {
//控制台打印
System.out.println(val);
}
};
demo.printSomething(something, printer);
}

至此我们都尚未使用lambda表达式。我们仅创建了Printer接口的具体实现,并将其传递给printSomething方法。

三、lambda表示式实现方式

关于lambda表达式概念后文再说,我们先来学习一下lambda表达式的语法:

(param1,param2,param3 ...,paramN)-  > {   //代码块;  }
  • 首先我们知道lambda表达式,表达的是接口函数
  • 箭头左侧是函数的逗号分隔的形式参数列表
  • 箭头右侧是函数体代码

现在,我们使用lambda表达式重构一下第一小节中的代码

public static void main(String[] args) {
LambdaDemo demo = new LambdaDemo();
String something = "I am learning Lambda";
//实现Printer接口(请关注下面这行lambda表达式代码)
Printer printer = (String toPrint)->{System.out.println(toPrint);};
//调用接口打印
demo.printSomething(something, printer);
}

lambda表达式使我们代码更简洁。实际上使用lambda表达式在性能和多核处理还有更多的好处,但是只有在理解java8 Streams API之后它们才有意义,因此不在本文讨论范围之内(本号之前的文章都有介绍)。

对比传统java代码的实现方式,代码量是不是减少了很多?但这仍然不是最简的实现方式,我们一步一步来。

Printer printer = (String toPrint)->{System.out.println(toPrint);};
//简化:去掉参数类型
Printer printer = (toPrint)->{System.out.println(toPrint);};
//简化:去掉参数括号
Printer printer = toPrint->{System.out.println(toPrint);};
//简化:去掉函数体花括号
Printer printer = toPrint->System.out.println(toPrint);
  • 即使没有在箭头的左侧指定参数的类型,编译器也会从接口方法的形式参数中推断出其类型
  • 当只有一个参数的时候,我们完全可以省略参数的括号
  • 当函数体只有一行的时候,我们完全可以省略函数体花括号

如果我们的接口方法定义不带任何参数,则可以用空括号替换:

()->  System.out.println("anything you wan to print")

那么,我们最终通过lambda表达式,简化完成的代码是什么样的呢?庐山真面目:


public static void main(String[] args) {
LambdaDemo demo = new LambdaDemo();
String something="I am Lambda";
//关注下面的这行代码
demo.printSomething(something, toPrint -> System.out.println(toPrint));
}

我们使用lambda表达式内联为函数调用参数,将最初main方法的9行代码下降到只有3行。但笔者要说,这仍然不是lambda表达式可以完成的最终极代码简化方式,当你学习了java8 Stream API结合lambda表达式使用,你会发现你的编码效率将大幅度提高!

结论

lambda表达式表达的是接口函数,箭头左侧是函数参数,箭头右侧是函数体。函数的参数类型和返回值类型都可以省略,程序会根据接口定义的上下文自动确定数据类型。

在这篇文章中,我们对Java中的Lambda表达式进行了详尽的介绍,并了解了如何使用它们来提高接口实现效率和质量。请关注本号更多有关内容,Stream API与Collections框架一起使用时为Lambda提供了更多优势。

欢迎关注我的博客,里面有很多精品合集

  • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

恕我直言你可能真的不会java第1篇:lambda表达式会用了么?的更多相关文章

  1. 恕我直言你可能真的不会java第2篇:Java Stream API?

    一.什么是Java Stream API? Java Stream函数式编程接口最初是在Java 8中引入的,并且与lambda一起成为Java开发的里程碑式的功能特性,它极大的方便了开放人员处理集合 ...

  2. 恕我直言你可能真的不会java第4篇:Stream管道流Map操作

    一.回顾Stream管道流map的基础用法 最简单的需求:将集合中的每一个字符串,全部转换成大写! List<String> alpha = Arrays.asList("Mon ...

  3. 恕我直言你可能真的不会java第8篇-函数式接口

    一.函数式接口是什么? 所谓的函数式接口,实际上就是接口里面只能有一个抽象方法的接口.我们上一节用到的Comparator接口就是一个典型的函数式接口,它只有一个抽象方法compare. 只有一个抽象 ...

  4. 恕我直言你可能真的不会java第11篇-Stream API终端操作

    一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之前 ...

  5. 恕我直言你可能真的不会java第12篇-如何使用Stream API对Map类型元素排序

    在这篇文章中,您将学习如何使用Java对Map进行排序.前几日有位朋友面试遇到了这个问题,看似很简单的问题,但是如果不仔细研究一下也是很容易让人懵圈的面试题.所以我决定写这样一篇文章.在Java中,有 ...

  6. 恕我直言你可能真的不会java第6篇:Stream性能差?不要人云亦云

    一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位 ...

  7. 恕我直言你可能真的不会java第7篇:像使用SQL一样排序集合

    在开始之前,我先卖个关子提一个问题:我们现在有一个Employee员工类. @Data @AllArgsConstructor public class Employee { private Inte ...

  8. 恕我直言你可能真的不会java第3篇:Stream的Filter与谓词逻辑

    一.基础代码准备 建立一个实体类,该实体类有五个属性.下面的代码使用了lombok的注解Data.AllArgsConstructor,这样我们就不用写get.set方法和全参构造函数了.lombok ...

  9. 恕我直言你可能真的不会java第5篇:Stream的状态与并行操作

    一.回顾Stream管道流操作 通过前面章节的学习,我们应该明白了Stream管道流的基本操作.我们来回顾一下: 源操作:可以将数组.集合类.行文本文件转换成管道流Stream进行数据处理 中间操作: ...

随机推荐

  1. zqt_helper 轻松开发Qt5 Widgets应用

    目标: 1. 代码更加紧凑,所写即所到. 2. 代码层次更直观,直接反映界面窗口层次关系. 3. 不继承类,不重写虚函数,slot接收QEvent. 4. 简单写布局,忘掉api函数. 5. 免去一大 ...

  2. 【github技巧2】下载包加速

    打开代下网站:https://g.widora.cn 直接输入     https开头的github地址 或需下载包地址的链接 获取链接 下载压缩包 备注:压缩包格式为tar,需要解压

  3. jdk8 Collections#sort究竟做了什么

    前言 Collections#sort 追踪代码进去看,会调用到Arrays.sort,看到这里时,你肯定会想,这不是很简单,Arrays.sort在元素较少时使用插入排序,较多时使用快速排序,再多时 ...

  4. Kubernetes实践踩坑系列(一).应用管理的难题

    应用管理的两大难题  今天我们主要讨论这两个方面的挑战: 对应用研发而言,K8s API 针对简单应用过于复杂,针对复杂应用难以上手: 对应用运维而言,K8s 的扩展能力难以管理:K8s 原生的 AP ...

  5. vue-cli3区分开发和生产环境

    vue-cli3出来很久了,之前一直使用vue-cli2的配置,并且区分了生产和开发环境,自己的理解,环境分两大类,开发环境 和生产环境,最近升级到了vue-cli4当然改动并不大. 升级的主要原因嘛 ...

  6. MRCTF 2020 WP

    MRCTF 2020 WP 引言 周末趁上课之余,做了一下北邮的CTF,这里记录一下做出来的几题的WP ez_bypass 知识点:MD5强类型比较,is_numeric()函数绕过 题目源码: I ...

  7. 第一次写js轮播图

    仿小米首页轮播图(注意事项) 布局部分 1.用ul包裹li再包裹a的形式来装图片,建立focus类: <div class="focus"> <ul> &l ...

  8. 关于vue的多页面标签功能,对于嵌套router-view缓存的最终无奈解决方法

    最近写我自己的后台开发框架,要弄一个多页面标签功能,之前有试过vue-element-admin的多页面,以为很完美,就按它的思路重新写了一个,但发现还是有问题的. vue-element-admin ...

  9. 添加对docker的监控

    一.环境:已安装docker机器ip:192.168.0.202 二.原理 使用docker的metrics-add参数,提供对docker运行参数的访问条件. 三.修改/etc/docker/dae ...

  10. DCL单例为什么要加Volatile

    拿一个对象创建赋值来说 class T{ int elem = 1; } T t = new T(); 上段代码转换成汇编码为: 0 new #2 <T> 3 dup 4 invokesp ...