Lambda 表达式

简介:

  • Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
  • Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
(parameters) -> expression

(parameters) ->{ statements; }

使用 Lambda 表达式需要注意以下两点:

  • Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
  • Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。

变量作用域

lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误 。

我们也可以直接在 lambda 表达式中访问外层的局部变量。

final int num = 1;
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); // 输出结果为 3

lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

方法引用

  • 方法引用通过方法的名字来指向一个方法。
  • 方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
  • 方法引用使用一对冒号 :: 。

函数式接口

函数式接口

有且只有一个抽象方法的接口,称之为函数式接口。当然接口中可以有其他方法(默认,静态,私有)

@FunctionInterface注解:可以检测接口是否是函数式接口

是:编译成功, 否:编译失败

函数式接口的使用:

一般可以作为方法的参数和返回值类型

例子:

1.定义一个函数式接口MyFunctionInterface中定义一个没有返回值的方法public void method();

2.定义一个接口的实现类MyFunctionInterFaceImpl实现函数式接口

3.定义一个测试类Demo中有一个静态方法show参数是这个函数式接口,调用接口中的方法public static void show(MyFunctionInterface myface){myface.method();}

4.在main方法中调用show方法的3中方式

a.调用show方法,参数是接口,所以可以传接口的实现类

show(new MyFunctionInterfaceImpl());

b.方法参数是一个接口,所以可以传递接口的匿名内部类

show(new MyFunctionInterface(){

@override

public void method(){System.out.print(“使用匿名内部类重写接口中的抽象方法”);}

});

c.调用show方法,方法参数是一个函数式接口所以可以使用Lambda表达式

show(()->{System.out.print(“使用lambda重写接口中的抽象方法”)});

函数式编程

  1. 函数式编程:使用Lambda表达式和方法引用简化程序。
  2. Lambda表达式的延迟执行:有些场景的代码执行后,结果不一定会被使用,从而造成性能的浪费。而Lambda是延迟执行的,这正好可以作为解决方法,提升性能。
  3. 函数式接口作为方法的参数和返回值。

    存在函数式接口就可以使用Lambda表达式。即可以使用Lambda进行传参。

使用Lambda优化日志案例:

1.Lambda的特点:延迟加载 lambda使用的前提:必须存在函数式接口(定义拼接字符串的接口)
2.使用Lambda表达式作为参数传递,仅仅是把参数传递showLogger方法中,只有满足条件,日志的等级是1级才会调用接口MessageBuilder中的方法builderMessage才会进行拼接字符串。

常用的函数式接口(java.util.function包中)

Supplier接口

Java.util.function.Supplier<T> 接口中仅包含一个无参的方法:T get()。
用来获取一个泛型参数指定类型的接口数据。
由于是一个函数式接口,这就意味着对应的Lambda表达式对外提供一个符合泛型类型的对象数据.
Supplier<T>接口被称为生产型接口,指定接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据

Consumer接口

Java.util.function.Consumer<T>接口正好与Supplier接口相反,他不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。
Consumer中包含抽象方法void accept(T t),意为消费一个指定泛型的数据。
Consumer接口是一个消费型接口,泛型执行什么类型,就可以使用accept方法消费什么类型的数据

.foreach(Consumer t)

Consumer中的默认方法andThen:组合消费   练习题
如果一个方法的参数和返回值全是Consumer类型,那么就可以实现效果:
消费的时候,首先做一个操作,然后再做一个操作,实现组合。要想实现组合,就需要两个个Lambda表达式。

Predicate接口 判断

Java.util.function.Predicate:
Predicate接口对某种数据类型进行判断,从而得到一个boolean值结果。
Predicate接口中的抽象方法:boolean Test(T t)用来对指定类型的数据进行判断方法
结果:符合条件:返回true
不符合条件:返回flase
默认方法:and or ! 练习题

.filter(Predicate t)

Function接口

Java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。
抽象方法:R apply(T t) 根据T的类型参数获取R类型的结果

.map(Function<Object, Object> f)

Java8特性Lambda表达式的更多相关文章

  1. Java8新特性-Lambda表达式是什么?

    目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...

  2. 乐字节-Java8新特性-Lambda表达式

    上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...

  3. Java 8 新特性 - Lambda表达式

    Lambda表达式 vs 匿名类既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析.一个关键的不同点就是关键字 this.匿名类的 this 关键字指向匿名类 ...

  4. Java8中Lambda表达式的10个例子

    Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 //Before Java 8: new Thread(new Runnable() { @Overri ...

  5. java8的lambda表达式,将List<DTO> 转为 List<DO>

    将List<PhoneDTO>转为List<PhoneDO>,通过java8的lambda表达式来操作,比传统的for循环精简很多: /** * List<PhoneDT ...

  6. JDK8 新特性 Lambda表达式

    1.java8中Lambda表达式基础语法: (x,y) -> {} 左侧是一个小括号,里面是要实现的抽象方法的参数,有几个参数就写几个参数名,无参可写空括号,无需声明参数类型: 中间是一个jd ...

  7. java8的lambda表达式

    关于java8的lambda表达式 lambda表达式一般用于接口,因为lambda表达式是函数式编程. 1.有且仅有一个抽象方法被称为函数式接口,函数式接口可以显示的被@FunctionalInte ...

  8. C#10新特性-lambda 表达式和方法组的改进

    C# 10 中对Lambda的语法和类型进行了多项改进: 1. Lambda自然类型 Lambda 表达式现在有时具有"自然"类型. 这意味着编译器通常可以推断出 lambda 表 ...

  9. java8新特性——Lambda表达式

    上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...

随机推荐

  1. windows上安装和使用ab压测工具

    ApacheBench是一款压力测试工具,用于测试http服务器请求的性能情况. 官方下载链接:https://www.apachehaus.com/cgi-bin/download.plx 百度云: ...

  2. Koa - 初体验(写个接口)

    前言 不会node.js的前端不是一个好前端! 这几年node.js确实是越来越火了,好多公司对node.js都开始有要求.虽说前端不一定要会后端,但想要成为一个优秀的前端,node.js是必经之路. ...

  3. 学Maven,这篇万余字的教程,真的够用了!

    1 Maven 介绍 1.1 为什么使用 Maven 由于 Java 的生态非常丰富,无论你想实现什么功能,都能找到对应的工具类,这些工具类都是以 jar 包的形式出现的,例如 Spring,Spri ...

  4. 使用Spring Boot和AspectJ实现方法跟踪基础结构

    了解如何使用Spring Boot和AspectJ实现方法跟踪基础结构!最近在优锐课学习收获颇多,记录下来大家一起进步! 在我们的应用程序中,获取方法的堆栈跟踪信息可能会节省很多时间.具有输入输出参数 ...

  5. Python3 并发编程4

    目录 Event事件 线程池与进程池 基本概念 使用方法 和信号量的区别 协程(coroutine) 基本概念 实现方式 多线程爬取梨视频 Event事件 用来控制线程的执行 e.isSet()查看对 ...

  6. Orleans[NET Core 3.1] 学习笔记(二)Hello World

    项目结构 开始Orleans之前,我们都知道Orleans主要可以分为俩部分,Host和Client. 所以我们可以创建如下的项目结构: IGrain 一个包含Grain接口的库(.NET Stand ...

  7. node+express 配置安装以及数据解析,cookie,session

    一.express安装,创建服务 (1)安装:npm install express --save(2)创建服务 server.js: const express = require('express ...

  8. 【NodeJS】nvm

    [NodeJS]nvm node多版本管理 NVM_HOME=C:\env\nvm NVM_SYMLINK=C:\env\nodejs 查看版本 nvm v 查看当前使用的node版本 nvm cur ...

  9. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

  10. 【ES6】数组的扩展——扩展运算符

    1.扩展运算符[三个点(...)将一个数组转为用逗号分隔的参数序列] 作用:用于函数调用 function add(x, y) { return x + y; } const numbers = [2 ...