Java8系列之 Lambda表达式(一)

简介: Java8系列之 Lambda表达式(一)

1策略模式之代码传递


软件开发中经常遇到这样的情况,某一功能在不同的条件或执行环境需要采用不同的算法或策略进行执行,而这些策略针对的对象却具有相通性,例如查找、排序等操作。针对这样的场景,程序员往往将不同的策略执行代码封装成不同的函数调用,结合if-else的方式进行策略的调用。的确这是一种很符合软件开发思维的处理方式,但是同时也带来了一些问题,因为这样的处理方式将策略进行硬编码化了,使得策略与程序执行的过程以及执行对象耦合度过高,代码的灵活性大大降低, 同时使得维护也较为困难。例如如果我们需要置定新的策略,往往就需要修改代码来实现了策略模式的思想就是将执行对象与算法解耦,对象无法感知也无需感知策略的具体执行方式,从而为代码带来的更高的灵活性其实Java中的基本的线程操作便是一种策略模式的体现,线程对象不可能提前得知线程执行函数的逻辑,所以定义了线程执行的策略接口Runnable,程序员只需按照Runnable接口实现一个线程策略实例,便可以使用Thread类来开启线程的执行了。线程执行代码如下:


image.png



如果从另一个角度看待策略模式,实际上策略模式一种行为参数化代码传递的技术,将具体的执行代码(行为)传递给对象制定的执行器进行执行,上面的例子其实可以看做将线程的执行代码传递给了线程对象的执行器去执行的过程。在Java 8中,提供了一种更直接的代码传递方式:Lambda表达式,通过使用Lambda表达式可以将上述代码精简到以下两行:


image.png


2

2什么是Lambda表达式


为了为大家带来最直观的Lambda表达式的理解,我们依旧采用前文学生筛选的例子。现在我们需要通过数学成绩进行排序,在以往开发中,我们可以通过实现Comparator接口的方式来实现该策略,如下:


image.png

使用Lambda之后可以这样表示比较策略:


image.png

不得不承认Lambda表达式使代码看起来更加清晰了!要是现在你觉得Lambda表达式看起来还是一头雾水,没有问题,随着分析的深入,你很快就会熟悉并喜欢上它的。Lambda表达式大体上可以分为三个部分,如下图:


image.png

  • 参数列表:这里的参数列实际上就是Comparator中的compare方法的参数列表,这里是两个参与比较的Student对象。
  • 箭头: 箭头是lambda表达式的标志,用于分割参数列表与表达式主体。
  • Lambda主体 :便是执行代码主体,这里是学生比较的策略实现代码。Lambda主体就相当于函数体,其可以使用参数列表中的变量。


Java语言设计者之所以选择这样的语法表达方式,是借鉴了C#和Scala语言中Lambda表达式的成功实践,并且这种方式在开发者中广受欢迎。Lambda的基本语法可以表示成如下模式:

    parameter, ...) ->  ( expression )

此外Lambda主体还可以包含多行代码,但需要采用花括号包含 :

    parameter, ... ) -> {  statements; ....;   }


3

3函数式接口


相信通过前面的分析,读者这里应该对于Lambda表达式有了一个初步的了解,这里我们在来说一下Lambda表达式的返回值问题。Lambda表达式的值就是Lambda主体代码的返回值,例如上面数学成绩比较的表达式就返回一个int变量;线程使用的lambda表达式以void返回。你可能会好奇,java如何对lambda表达式进行类型检查?这里我们放在后节讲解,这里先来看一下什么是函数式接口。现在你可能在问,我们在什么地方可以使用Lambda表达式?在java 8规定在声明了函数式接口的类上可以使用Lambda表达式,例如Runnable接口,Callable接口,Comparator接口。那么到底什么是函数式接口?函数式接口就是只定义了一个抽象函数的接口


image.png


Lambda表达式允许你直接以内联的方式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例,也就是说这个Lambda表达式就是接口具体实现的一个实例。这里我想同学们应该能理解为何函数式接口只允许声明一个抽象函数了吧,假设可以声明多个,那么Lambda表达式在解析时就会存在多态解析问题,毕竟Lambda是匿名函数,这无疑会给java的语言特性以及使用者带来额外的负担。在JDK8中提供了@FunctionInterface注解来专门表示函数式接口,会对接口的声明进行语法检查,当然 注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错,例如“Mutiple non-overriding abstract methods found ininterface xxx”,说明存在多个抽象方法,这是不允许的。


4关于函数描述符


函数式接口的抽象方法的签名基本上就是Lambda表达式的签名。我们将这种抽象方法叫做函数描述符。写过JNI的同学一定会知道Java函数签名。函数签名表示了一个函数的返回值、参数列表、以及函数性质,当然具体使用者将变量名命名成什么或者函数名叫什么都不是函数签名考虑的,读者可以将签名理解为函数类型的一种描述,实质上Java的函数类型检查就是基于签名来做的,只要签名相同,那么就可以认为具有相同的函数声明定义。Lambda表达式也一样,对于表达式的具体实现,一定要与接口的函数签名相匹配,否则会语法报错,这也不难理解。例如Comparator接口的抽象函数表示了一个接受两个对象并返回一个int变量的函数签名。我们将Comparator的函数描述符使用(Object,Object) -> int的形式来表述,在本系列文章中也会沿用这样的描述方式。



Lambda表达式是开启Java 8 新语言特性的起点,之后的语言特性很多都是以Lambda为基础来展示的。这里我们一定要理解Lambda表达式正是函数式接口的具体的实现这一重要性的意义,同时这也是Java 8 对于Lambda表达式语法正确性检查的函数描述符依据。之后我们将会讨论函数描述符、Lambda的类型检查等主题;它们都是建立本文的基础之上来讨论的。



相关文章
|
4天前
|
自然语言处理 安全 Java
Aviator Java 表达式引擎
AviatorScript 是一门高性能、轻量级寄宿于 JVM 之上的脚本语言。
22 10
|
2天前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
18天前
|
Java 数据库
案例一:去掉数据库某列中的所有英文,利用java正则表达式去做,核心:去掉字符串中的英文
这篇文章介绍了如何使用Java正则表达式从数据库某列中去除所有英文字符。
32 15
|
5天前
|
Java API
[Java]Lambda表达式
本文主要介绍了Java中的Lambda表达式,包括其优化匿名内部类的方式、使用规范、内置函数式接口及方法引用等内容。文章详细解析了Lambda的基础语法、参数列表、方法体的简化规则,以及如何利用Lambda优化代码。此外,还探讨了Lambda的作用域和引用规则,强调了对局部变量、成员变量和常量的访问限制,旨在帮助读者全面理解和掌握Lambda表达式的应用。
[Java]Lambda表达式
|
15天前
|
Java 程序员 API
Java中的Lambda表达式:简化代码的秘密武器
【10月更文挑战第11天】 在Java编程中,Lambda表达式是一种简洁而强大的工具,它允许我们将函数作为参数传递给其他方法。本文将介绍Lambda表达式的基本概念、使用方法以及在实际项目中的应用案例,帮助你更好地理解和利用这一特性来简化代码。
21 8
|
8天前
|
Java 测试技术 开发者
🌟Java零基础-Lambda运算符详解 🌟
【10月更文挑战第12天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
16 1
|
18天前
|
并行计算 Java API
Java中的Lambda表达式及其应用
本文将深入探讨Java中的Lambda表达式,从基本概念到实际应用。我们将了解Lambda表达式的定义、优势和使用场景,并通过实例展示其在Java编程中的强大功能。无论是初学者还是经验丰富的开发者,都可以从中获得有价值的见解。
|
16天前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
20 1
|
21天前
|
并行计算 Java API
探索Java中的Lambda表达式:简化代码,提高可读性
【10月更文挑战第5天】Lambda表达式在Java 8中引入,旨在简化集合操作和并行计算。本文通过介绍Lambda表达式的基本概念、语法结构以及实际应用示例,展示了如何利用这一特性编写更加简洁、易读的代码。我们将从Lambda的基础入手,逐步深入到其在函数式接口中的应用,并探讨其对Java编程范式的影响。
|
20天前
|
XML Java 数据格式
Java正则表达式大全(参考)
Java正则表达式大全(参考)