可能很多人都听说过java8的新特性----Lambada表达式,但可能很多人都不知道Lambda表达式到底有什么用,下面我带大家理解一下Lambada表达式。

在平时的编程中,我们常常会用到匿名内部类,见下面代码:

package 示例;

import static org.junit.Assert.*;//

import org.junit.Test;

public class LambdaTest {
@Test
public void testOld1() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("原始方法使用匿名内部类");
} }).start();
}
}

上述代码运用到了匿名内部类,但你们有没有发现,接口名和方法名在这段代码逻辑中是固定的,也就是说我们通过实现Runnable接口就必定实现父类接口中的run方法。写一万次上述代码,只有run方法内部的算法逻辑是改变的。

java8也就引入了一个新特性-----Lambda表达式

package 示例;

import static org.junit.Assert.*;

import org.junit.Test;

public class LambdaTest {
@Test
public void testNew1(){
/*此处用Lambda表达式,省略了接口名“new Runnable(){}”,以及接口中需要实现的方法名,以及修饰方法关键字(public void),只留下run方法用来传参数的“()”。因为run方法没有参数,所以括号中什么也没有   (这里的圆括号就是run方法的括号,只是省略了方法名)*/
new Thread(()->System.out.println("Lambda表达式")).start();
}
}

在上面的代码中,我们用Lambda表达式代替了传统的匿名内部类形式的Java代码,Lambda表达式如下:

()->System.out.println("Lambda表达式")

被替换的传统代码如下:

new Runnable(
public void run(){
System.out.println("匿名内部类");
}
)

(一)我们现在来看看为什么可以省略这些东西呢

(1)为什么可以省略接口名:

因为在Lambda表达式外面有new Thread()。而我们根据多线程的学习知道,Thread类的构造器如果只传入一个参数,那必定是Runnable接口实现类的实例。

public Thread(Runnable target)

所以编译器在编译的时候,是可以推断出来我们后面匿名内部类实现的接口是什么(Lambada表达式就是匿名内部类的精简写法),因此Lambda表达式将接口名省略。

 (2)为什么可以省略接口中的方法名

通过上面我们知道了,编译器可以推导匿名内部类实现的接口名。那Runnable接口中只有一个抽象方法,因此编译器同样可以推导出实现类中的方法名。

(二)Lambda表达式的具体语法

语法:(参数列表)->{函数体};

注:Lambda表达式省略了匿名内部类的接口名、和方法名,目的就是让我们专注于接口方法的实现部分。

(1)参数列表规则

  1. 如果没有参数,直接用“()”表示。()不能省略。

  2. 如果只有一个参数,并且参数写了类型,则一定要加()

  3. 如果只写了一个参数,并且参数不写类型,那么这个参数外面不用加“()”。

  4. 如果有两个或多个参数,则“()”必须写。

(2)函数体规则

  1. 如果函数体只有一行,那么可以省略“{}”。
  2. 如果函数体有多行,则“{}”不能省略。
  3. 如果函数体有多行,并且该函数有返回值,则不能省略“return”关键字。
  4. 如果函数体是一行,并且函数有返回值,则必须省略“return”关键字(由编译器自己推导返回类型)

java8引入Lambda表达式的唯一目的就是简化函数式接口的使用。(暂时可以理解为简化匿名内部类的使用)

(三)Lambda表达式异常处理

  1. Lambda表达式产生的异常在函数体中try-catch。
  2. 在接口的抽象方法定义时,声明抛出异常。

(四)Lambda表达式使用场景(局限性)

      由上面的的学习可知,Lambda表达式实际上就是匿名内部类的一种精简写法。在编译时还是会被推导为匿名内部类,说白了Lambda表达式就是一种“语法糖”。根据Lambda表达式省略接口名与方法名的原理可知,只有在编译器自身能够推导出匿名内部类实现的接口时,才能使用Lambda表达式。在能够推导出接口后,必须满足接口中只有一个抽象方法才能运用Lambda表达式。

补充说明:在Java中,通常将只有一个抽象方法的接口称为函数式接口,我们可以在接口上添加“@FunctionalInterface”标签,表明这是一个函数式接口。

总结

Java8新增的这一特性唯一的目的就是简化函数式接口的使用,它本身不是一个新的语法知识,底层实际上还是匿名内部类,所以学会灵活使用Lambda表达式,可以提高代码的开发效率,但在后期维护中降低了代码的可读性,博友们可以尝试一下这种“语法糖”。

下面是博主的其他文章,喜欢的博友点个关注,感谢您的支持。

JDK8以前匿名内部类访问局部变量为什么必须用final修饰

Validate插件的自定义表单校验入门(结合Ajax实现用户名的数据库查重)

EL表达式与JSTL简单入门

JSON转换工具的使用

Java8 Lambda表达式入门的更多相关文章

  1. java8 Lambda表达式的新手上车指南(1)

    背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...

  2. java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口

    背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...

  3. 函数式编程/lambda表达式入门

    函数式编程/lambda表达式入门 本篇主要讲解 lambda表达式的入门,涉及为什么使用函数式编程,以及jdk8提供的函数式接口 和 接口的默认方法 等等 1.什么是命令式编程 命令式编程就是我们去 ...

  4. Java Lambda表达式入门

    Java Lambda表达式入门 http://blog.csdn.net/renfufei/article/details/24600507 Java 8十个lambda表达式案例 http://w ...

  5. Java学习笔记--Java8 Lambda表达式

    Java Lambda表达式入门:http://blog.csdn.net/renfufei/article/details/24600507 lambda内容的介绍:http://swiftlet. ...

  6. Java8 Lambda表达式详解手册及实例

    先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下 ...

  7. Java8 Lambda表达式(一)

    目录 一.应用场景引入 优化一:使用策略模式 优化二:使用匿名内部类 优化三:使用Lambda表达式 优化四:使用Stream API 二.Lambda运算符和对应语法 语法格式 Lambda表达式需 ...

  8. Java8 Lambda表达式、函数式接口和方法引用

    目录 Java8 Lambda表达式和函数式接口 Lambda表达式 Lambda的使用 函数式接口FunctionalInterface Java内置四大核心函数式接口 方法引用 构造器引用 Jav ...

  9. java8之lambda表达式入门

    1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ privat ...

  10. java8 快速入门 lambda表达式 Java8 lambda表达式10个示例

    本文由 ImportNew - lemeilleur 翻译自 javarevisited.欢迎加入翻译小组.转载请见文末要求. Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发 ...

随机推荐

  1. ssm 创建bean的三种方式和spring依赖注入的三种方式

    <!--创建bean的第一种方式:使用默认无参构造函数 在默认情况下: 它会根据默认无参构造函数来创建类对象.如果 bean 中没有默认无参构造函数,将会创建失败--> <bean ...

  2. .gitignore 基础

    前言 gitignore文件有几种方式生成. 1.在创建版本库的时候生成. 2.自己手动添加: windows环境下,不能把文件直接改名为.gitignore,会提示你必须输入文件名.所以我们先新建一 ...

  3. 重新整理数据结构与算法(c#)—— 算法套路动态规划算法[二十六]

    前言 动态规划算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法. 这样一听和分治算法有点相似啊. 是的,分治算法也是将大问题分为小问题,但是他们毕竟不同,不同之处在什么地 ...

  4. .NET8中的Microsoft.Extensions.Http.Resilience库

    接上一篇,https://www.cnblogs.com/vipwan/p/18129361 借助Aspire中新增的Microsoft.Extensions.ServiceDiscovery库,我们 ...

  5. 常用注解使用总结系列: @Order 注解

    @Order 注解 @Order注解主要用来控制配置类的加载顺序示例代码: package com.runlion.tms.admin.constant; public class AService ...

  6. 搞定了 6 种分布式ID,分库分表哪个适合做主键?

    大家好,我是小富- 本文是<ShardingSphere5.x分库分表原理与实战>系列的第七篇,目前系列的前几篇制作成了PDF,需要的可以在文末获取下载方式,持续更新中.今天咱们继续一起来 ...

  7. Thinkphp5.x全漏洞复现分析

    基础知识 命名空间和子命名空间 我们可以把namespace理解为一个单独的空间,事实上它也就是一个空间而已,子命名空间那就是空间里再划分几个小空间,举个例子: <?php namespace ...

  8. 力扣239(Java)- 滑动窗口最大值(困难)

    题目: 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回 滑动窗口中的最大值 . 示 ...

  9. 《领域驱动设计》:从领域视角深入仓储(Repository)的设计和实现

    简介: <领域驱动设计>中的Repository(下面将用仓储表示)层实际上是极具有挑战性的,对于它的理解,也十分重要.本文讲大部分内容都在众多前辈理论基础上,从一个崭新的领域视觉开始探索 ...

  10. 一文读懂 BizDevOps:数字化转型下的技术破局

    简介: 目标.方法与实践. 我们正迈向数字经济时代,数字化转型成为普遍行动.未来绝大多数业务都将运行在数字基座之上,软件系统成为业务创新和发展的核心引擎.在这一趋势下,产品研发的交付能力面临巨大挑战, ...