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. JavaScript基础4

    数组 创建数组  A.通过构造函数创建数组 * a): var arr=new Array();//定义一个空数组,无长度的空数组. * b):var arr1=new Array(num); * 当 ...

  2. POJ2528 Mayor's poster

    The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign h ...

  3. unordered_map / HashTable 的负载因子是什么意思

    // in C++ 前段时间在看一些关于这个的文章时遇到了一些问题:unordered_map / HashTable 的负载因子是什么意思 经过度娘的搜索,最后得出: 若设 Hash 表的桶数量为 ...

  4. docker-网络管理-桥接网络

    一.配置桥接网络   需求:为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求.这个需求其实很容易实现,我们只要将Docker容器和宿主机的 ...

  5. vue click.stop阻止点击事件继续传播

    <div id="app"> <div @click="dodo"> <button @:click="doThis&q ...

  6. 一文搞清楚Minor GC、Major GC 、Full GC 之间的关系

    前言 文章要求读者熟悉 JVM 内置的通用垃圾回收原则.堆内存划分为 Eden.Survivor 和 Tenured/Old 空间,代假设和其他不同的 GC 算法超出了本文讨论的范围. Minor G ...

  7. GoLand不同目录(包)方法调用

    新手学go,跨目录调用方法是真的难,弄了好几天,几乎要放弃go了,在此演示一下如何跨目录(包)调用~ 需求是main.go调用model包下mysql.go中Query方法,目录结构如下. 要点: 1 ...

  8. .NET 中数据访问用的 DBHelper(Sql Server) 类

    public class DBHelper { private static string DBConnectString = "Data Source=.;Initial Catalog= ...

  9. C# WPF实用的注册窗体

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

  10. Redis-API

    Redis-API 简介 Redis 是一个基于内存的高效的键值行非关系型数据库,存取效率极高. python提供了两个类:分别为Redis和StrictRedis来实现Redis的命令操作.Redi ...