Java8之前,Java中的一切都是围绕着“对象“展开的,将”面向对象编程“的理念贯彻到底,但是随着python、scala等拥有函数式编程风格的语言兴起,Java为了维护自己强大的生态圈,于是在Java8引入了函数式接口和Lambda表达式来进行一定程度的函数式编程开发。
- 函数式接口
函数式接口是Java8的一个非常重要的新特性,函数式接口是指有且必须只能有一个抽象方法的接口(默认方法个数没有限制),如Runnable接口、Consmer接口等
标记这个注解@FunctionalInterface的作用就是申明这就是一个函数式接口,可以让Java编译器帮我们判断是否符合要求。但是不标记符合要求它也属于函数式接口。
Java8引入的四大核心内置函数式接口:
- Consumer:消费型接口(void accept(T t)),传一个参数,没有返回值(被消费了)
- Supplier:供给型接口(T get()),不用传参数,提供一个返回值(对外提供)
- Function<T, R>:函数型接口(R apply(T t)),传入一个类型参数,返回一个类型参数,当然他们可以一样
- Predicate:断言型接口(boolean test(T t)),传一个参数,返回boolean(判断是非)
还有一些其他类似的函数值接口,都在java.util.function
包下,像BiFunction<T, U, R>
参数两个T、U,返回R等
- Lambda表达式
我们都知道在Java8以前可以通过匿名内部类创建接口实例,该类接口通常也是只有一个抽象方法(属于函数式接口)。
但是现在在Java8环境下,我们可以使用Lambda表达式代替这种匿名内部类的写法。
Lambda表达式其实就是一个函数式接口的实例。
示例:
以前匿名内部类的写法:
public class LambdaTest {
@Test
public void lambdaTest() {
consumer(100, new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
}
private void consumer(Integer integer, Consumer<Integer> consumer) {
consumer.accept(integer);
}
}
现在使用Lambda表达式:
@Test
public void lambdaTest2() {
consumer(20, a -> System.out.println(a));
}
private void consumer(Integer integer, Consumer<Integer> consumer) {
consumer.accept(integer);
}
Lambda表达式解析:
- ”->“ 语法符号,表明这是一个Lambda表达式
- ”->“左边,表示该函数式接口的抽象方法的参数列表,参数类型可以省略(会自动判断),一个参数可以省略小括号,零个或多个参数不能省略小括号
- ”->“右边,表示抽象方法的方法体,一段语句的话可以省略大括号,省略大括号的情况下就必须省略
return
关键字
示例
/**
* 使用Lambda表达式:
*/
@Test
public void lambdaTest3() {
Integer function = function(10, (a) -> {
System.out.println(a);
return a * a;
});
System.out.println(function);
}
/**
* Function接口测试
*/
private Integer function(Integer integer, Function<Integer, Integer> function) {
return function.apply(integer);
}
- 总结
函数式接口就是该接口只有一个抽象方法,但是可以有多个默认方法(或者没有)
lambda表达式就是一个函数式接口的实例