java8新特性-lambda表达式

傷城~ 2023-02-20 03:13 283阅读 0赞

文章目录

  • 前言
  • 函数式接口
  • 基本格式
  • 简单示例
  • 作用域
  • Map.forEach()
  • Stream中的 lambda
  • 双冒号 :: 简写 lambda

在这里插入图片描述

前言

java 8 一个大亮点就是引入了 lambda 表达式,使得代码开发更加简单。主要用于定义行内执行的方法类型接口,比如有一个接口你懒得去实现然后调用其方法就可以写一个 lambda 表达式

lambda 表达式到底做了什么事呢?具体的理解就是它实际上是一个接口的匿名实现类,箭头后是对接口中的抽象方法进行了实现,箭头前是抽象方法的传参

函数式接口

我们在学习 java 8 的 lambda 表达式的时候,首先必须要知道的就是函数式接口,这个词和 java 8 lambda 表达式一起出现的,二者相辅相成,lambda 表达式是函数式接口的匿名实现

函数式接口,是一种特殊的接口,与 java 8 中 lambda 表达式同时被定义,jdk 中使用 @FunctionalInterface 标在接口上方,来指明此接口是函数式接口,作为函数是接口表示其可以接收 lambda 表达式作为该类接口的匿名实现,比如Map.forEach()方法中接收的是一个 BiConsumer 函数式接口,因此其中可以写 lambda 表达式表示匿名实现这个函数式接口

一般的接口中所有方法必须都是抽象方法,对于函数式接口中不仅可以定义静态方法,还可以定义 default 修饰的方法default void这样该函数是接口就可以直接 new 并且调用此方法

基本格式

->前为参数,后为函数表达式的返回

expression 是一般的表达式,比如可以是a+b,不加括号表示实现的方法返回是a+b

statements 表达式可以是a=1但是如果写a+b会报错,加了括号表示返回的是整个括号中内容

  1. (parameters) -> expression
  2. (parameters) -> {
  3. statements;}

简单示例

  1. public class JustForTest {
  2. @Test
  3. public void test() {
  4. A addition = (a, b) -> a + b;
  5. System.out.println(addition.caozuo(1, 2));
  6. }
  7. interface A {
  8. int sum(int x, int y);
  9. }
  10. }

这个示例简单明了,addition 就类似于一个接口实现类然后使用A addiction = new 接口匿名的实现类()一样的效果了。这种 lambda 表达式的运用可以帮助我们少些很多代码

作用域

我们下面直接看几个小例子

样例一

在 lambda 表达式中声明的变量不可以在表达式外部使用。其实也很好理解,因为表达式中实际等价于实现了一个匿名内部类,类中方法中的变量是不可以在外部使用的

\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jtive22c-1592835276134)(C:\\Users\\石磊\\AppData\\Roaming\\Typora\\typora-user-images\\1592820303720.png)\]

样例二

作为类的 field 变量,在方法中的 lambda 表达式里可以引用它,并且可以做修改。直接看下面的例子中 variable 吧

\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RVUW1kQU-1592835276136)(C:\\Users\\石磊\\AppData\\Roaming\\Typora\\typora-user-images\\1592819964526.png)\]

样例三

作为方法中的变量,方法中的 lambda 表达式中不可以修改此变量,在运行之前就可以检测出错误。下方红色波浪线。也就是说这时候其隐含了 final 属性

\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f7EVxJGU-1592835276142)(C:\\Users\\石磊\\AppData\\Roaming\\Typora\\typora-user-images\\1592820119347.png)\]

Map.forEach()

前文也提到了,forEach() 方法中接收一个函数式接口 BiConsumer,因此这里可以使用 lambda 表达式(该函数式接口的匿名实现)

  1. Map<String, String> map = new HashMap<>();
  2. map.put("a", "1");
  3. map.put("b", "2");
  4. map.forEach((key, value) -> {
  5. System.out.println(key + ":" + value);
  6. });

Stream中的 lambda

java 8 的流式处理也是一个很好新特性,它常常会伴随着 lambda 表达式一起使用,集合类调用流的stream() 方法,然后再调用 Stream 接口中的方法,这些方法中的参数很多都是接口,这样就可以做成 lambda 表达式了。

这里没有专门讲 Stream 流式处理,博主的另一篇博文:java8新特性-stream流式处理 专门有讲解

双冒号 :: 简写 lambda

双冒号::是用来简写 lambda 表达式,让其更加简洁,这种简写学名是η-conversion,读作eta-conversion。双冒号前面的为类名,后面是该类中的方法,整体表示匿名实现某个接口,接口中方法的实现使用的是该类中的方法

具体怎么理解呢?双冒号的整个表达式实际就是一个接口的匿名实现类,双冒号后是用什么已经实现的方法代替要实现的接口中的抽象方法,双冒号前指明是哪个类

举个例子,现在假如存在接口 A,我们来写个常规的 lambda 表达式

  1. interface A {
  2. int sum(int a, int b);
  3. }
  4. public class JustForTest {
  5. @Test
  6. public void test1() {
  7. A a = (a, b) -> a + b;
  8. }
  9. }

我们再用双冒号来实现

  1. interface A {
  2. int sum(int a, int b);
  3. }
  4. public class JustForTest {
  5. @Test
  6. public void test1() {
  7. A a = Integer :: sum;
  8. }
  9. }

发表评论

表情:
评论列表 (有 0 条评论,283人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JAVA8特性-lambda表达式

    摘要 一篇让你搞懂lambda表达式、函数式接口、方法引用、Optional这些JAVA8的新特性及相互间关系。下图是本文的内容概要 ![在这里插入图片描述][w...

    相关 Java 8特性lambda表达式

    lambda 表达式是 java 8th 给我们带来的几个重量级新特性之一,借用 lambda 表达式可以让我们的程序设计更加简洁。 一. 行为参数化 行为参数化简单的说就