Code前端首页关于Code前端联系我们

JAVA开发:什么是lambda表达式?它有什么作用?

terry 2年前 (2023-09-25) 阅读数 47 #后端开发

1.什么是Lambda?

我们知道我们可以为 Java 变量分配一个“值”。 JAVA开发:Lambda表达式是什么?有啥子作用?

将“代码块”分配给 Java 变量需要做什么?例如,将右侧的一段代码分配给名为 aBlockOfCode 的 Java 变量: JAVA开发:Lambda表达式是什么?有啥子作用?

在 Java 8 之前,这是不可能的。但从 Java 8 开始,这可以使用 Lambda 函数来完成。如图:JAVA开发:Lambda表达式是什么?有啥子作用?

当然,这不是一种非常简洁的写法。因此,为了让这个赋值操作更加简洁,我们可以去掉一些无用的声明,如下所示: JAVA开发:Lambda表达式是什么?有啥子作用?

这样,我们就成功非常优雅地将一段“代码”赋值给了一个变量。而“这段代码”或“分配给变量的这个函数”就是一个 lambda 表达式。但这里的问题仍然是,aBlockOfCode 变量应该是什么类型?

在 Java 8 中,所有 Lambda 类型都是一个接口,而 Lambda 表达式本身(即“一段代码”)必须是该接口的实现。这是理解 Lambda 的关键。简而言之,Lambda表达式本身就是一个接口的实现。继续阅读以便更容易理解。在上面的aBlockOfCode中添加一个类型: JAVA开发:Lambda表达式是什么?有啥子作用?

这种只需要一个接口函数的接口称为“函数式接口”。为了防止后来人们给这个接口添加接口函数,导致实现更多的接口函数,成为“非功能接口”,我们可以给这个接口添加@FunctionalInterface声明,这样别人就无法添加了。新接口函数:JAVA开发:Lambda表达式是什么?有啥子作用?

这就是如何获得完整的 lambda 表达式声明:JAVA开发:Lambda表达式是什么?有啥子作用?

2. lambda 表达式的函数是什么?

最直观的特点就是让代码变得非常简洁。

我们可以比较同一接口的Lambda表达式和传统Java实现:JAVA开发:Lambda表达式是什么?有啥子作用?

两种写法本质上是等价的。但显然,Java 8的写法更加优雅和简洁。而且,由于 Lambda 可以直接赋值给变量,所以我们可以直接将 Lambda 作为参数传递给函数,而传统 Java 必须有明确的接口实现和初始化定义:JAVA开发:Lambda表达式是什么?有啥子作用?

在某些情况下,这种实现该接口只需要使用一次。传统的 Java 7 应该要求您定义一个“污染”接口来实现 MyInterfaceImpl。相比之下,Lambda Java 8 看起来干净得多。

示例1:

Lambda结合FunctionalInterface Lib、forEach、stream()、方法引用等新函数可以让代码更加简洁!

假设给出了 person 的定义和 list 的值: JAVA开发:Lambda表达式是什么?有啥子作用?

现在我们需要打印有罪者列表中所有姓氏以“Z”开头的人的姓名。

Lambda的原始写法:定义两个函数式接口,定义一个静态函数,调用静态函数,将Lambda表达式赋给参数。 JAVA开发:Lambda表达式是什么?有啥子作用?

这段代码其实比较简洁,但是我们能更简洁一点吗?

当然可以。在Java 8中,有一个函数式接口包,定义了大量可以使用的函数式接口(java.util.function (Java Platform SE 8))。因此,我们甚至不需要在这里定义NameChecker和Executor这两个功能接口。我们可以简单地使用 Java 8 函数接口包中的 Predicate 和 Consumer - 因为它们是一对。接口定义实际上与NameChecker/Executor相同。 JAVA开发:Lambda表达式是什么?有啥子作用?

简化第一步——使用函数接口封装: JAVA开发:Lambda表达式是什么?有啥子作用?

对于静态函数中的每个循环其实非常有吸引力。这里你可以使用Iterable自己的forEach()来代替。 forEach() 本身可以接受 Consumer 参数。

第二步就简化了——使用Iterable.forEach()来代替foreach循环: JAVA开发:Lambda表达式是什么?有啥子作用?

由于静态函数实际上只执行列表操作,所以我们可以在这里去掉静态函数,直接使用stream( ) 函数来完成它。多个 Stream() 方法接受 Predicate 和 Consumer (java.util.stream (Java Platform SE 8)) 等参数。一旦理解了上面的内容,stream()就很容易理解了,不需要进一步解释。

第三步是简化——用stream()来代替静态函数:JAVA开发:Lambda表达式是什么?有啥子作用?

与原来写Lambda的方法相比,这非常非常简洁。但是如果我们请求更改为打印有关一个人的所有信息,并且 p -> System.out.println(p);那么我们可以使用方法参考继续化简。所谓方法引用就是用已编写的另一个对象/类的方法替换 Lambda 表达式。格式如下: JAVA开发:Lambda表达式是什么?有啥子作用?

步骤 4. 简化 - 如果 println(p),您可以使用方法引用来替换 forEach 中的 Lambda 表达式: JAVA开发:Lambda表达式是什么?有啥子作用?

这本质上是可以编写的最简洁的版本。 ? T>除非与Lambda结合使用,否则原本繁琐的空检查无法简化。 JAVA开发:Lambda表达式是什么?有啥子作用?

Optional只有与Lambda结合使用才能发挥其真正的威力!

现在我们来比较一下以下四种常见的 null 处理中 Java 8 中的 Lambda+Optional 与传统 Java 在 null 处理上的差异。

示例 1 - 如果存在,则运行操作 JAVA开发:Lambda表达式是什么?有啥子作用?

示例 2 - 如果存在,返回,如果不存在,返回屁 JAVA开发:Lambda表达式是什么?有啥子作用?

示例 3 - 如果存在,返回,如果不存在,函数生成它 JAVA开发:Lambda表达式是什么?有啥子作用?

示例 4 –致命的串行空检查JAVA开发:Lambda表达式是什么?有啥子作用?

从以上四种情况可以明显看出,Optional+Lambda 可以让我们编写更少的 ifElse 块。尤其是例 4 中致命的串行 null 检查,传统的 Java 写法显得冗长难懂,而新的Optional+Lambda 则清新精练、清晰简洁。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门