Lambda表达式
1、为什么JAVA需要Lambda表达式?
如果忽视注解(Annotations)、泛型(Generics)等特性,自 Java 语言诞生时起,它的变化并不大。Java 一直都致力维护其对象至上的特征,在使用过JavaScript 之类的函数式语言之后,Java 如何强调其面向对象的本质,以及源码层的数据类型如何严格变得更加清晰可感。其实,函数对Java 而言并不重要,在 Java 的世界里,函数无法独立存在(JAVA 8新特性)。
然而,在函数式编程语言中,函数是一等公民,它们可以独立存在,你可以将其赋值给一个变量,或将他们当做参数传给其他函数。JavaScript 是最典型的函数式编程语言。函数式语言提供了一种强大的功能——闭包,相比于传统的编程方法有很多优势,闭包是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。Java 现在提供的最接近闭包的概念便是 Lambda 表达式,虽然闭包与 Lambda 表达式之间存在显著差别,但至少 Lambda 表达式是闭包很好的替代者。
Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。尽管不完全正确,我们很快就会见识到 Lambda 与闭包的不同之处,但是又无限地接近闭包。在支持一类函数的语言中,Lambda 表达式的类型将是函数。但是,在 Java 中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface)。
补充:避免匿名内部类定义过多
2、函数式接口
什么是函数式接口?
函数式接口的定义:
- 任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。-
- eg:标准接口Runnable是一个函数式接口,因为只定义了一个方法run()。
- 对于函数式接口,我们可以通过lambda表达式来创建该接口的对象。
同时,Java8引入了一个新的注解:@FunctionalInterface
可以在任意函数式接口上面使用@FunctionalInterface来标识它是一个函数式接口,但是该注解不是强制的。
3、Lambda 进化史
1.定义函数接口,实现类
2.静态内部类实现
3.局部内部类
4.匿名内部类
5.用Lambda简化
4、常见用法
此种写法是Java8 Lambda表达式类名::方法名 Person::getName
2.表达式: HashMap::new,方法名可以是静态方法,实例方法。
方法引用 | Lambda |
String::value of | x->String.valueof(x) |
Object::toString | x->x.toString |
x::toString | ()->to.String |
ArrayList::new | ()->new ArrayList<>(); |
5、表达式的语法格式
- 无参数,无返回值
()->System.out.println("Hello,World");
- 有一个参数,并且无返回值
(x)->System.out.println("Hello,World");
- 有两个以上的参数,有返回值,并且Lambda体中有多条语句,大括号用来包括两条及以上的语句
数据类型可以不写,是因为JVM可以通过上下文推断出数据类型。
- 手写函数式接口,并实现Lambda表达式
- 定义一个函数式接口,接收两个泛型的参数,并且返回一个参数
- 定义一个方法,用来实现两个Long型数字的相加
- 测试