1、函数式接口
什么是函数式接口?
函数式接口指的是接口中只有一个抽象方法的函数。
说明:
- 函数式接口中可以包含默认实现的方法,即关键字为default开头的方法。
@FunctionalInterface
interface myFunctionInterface {
String getName();
//默认实现
default Integer getAge() {
return 25;
}
}
- 函数式接口中可以有静态实现方法,即方法带有static关键字的方法。
@FunctionalInterface
interface myFunctionInterface {
String getName();
//默认实现
static Integer getAge() {
return 25;
}
}
- 函数式接口中可以允许子接口继承多个父接口,但每个父接口只能存在一个抽象方法且必须是相同的抽象方法,否则子类就不是函数式接口。
@FunctionalInterface
interface MyFunctionInterface1 {
String getName();
}
@FunctionalInterface
interface MyFunctionInterface2 {
String getName();
}
//继承多个接口,但是多个父接口具有相同的抽象方法,所以该接口还是函数式接口
@FunctionalInterface
interface SubFunctionInterface1 extends MyFunctionInterface1 ,MyFunctionInterface1 {
@Override
String getName();
}
//继承多个接口,但是多个父接口具有相同的抽象方法,所以该接口不是函数式接口且编译报错
//错误信息Invalid '@FunctionalInterface' annotation; SubFunctionInterface1 is not a functional interface
@FunctionalInterface
interface SubFunctionInterface2 extends MyFunctionInterface1 ,MyFunctionInterface1 {
Integer getAge();
}
- java8中提供@FunctionInterface在类上标注说明该接口为函数式接口,在编译期间该接口不符合函数式接口条件则提示编译报错。
- Java8中增加了java.util.function包,该包包含了常用的函数式接口。如下表所示
接口名称 | 方法声明 | 功能说明 |
Consumer | void accept(T t) | 提供一个参数 |
Supplier | T get() | 得到一个返回值 |
Function<T,R> | R apply(T t) | 通过指定参数返回指定值 |
Predicate | boolean test(T t) | 判断条件是否满足 |
2、Lambda表达式
什么是Lambda表达式?
- lambda表达式也成为闭包,是java5以来以来最具有革命性的版本新特性,同时也是推动Java最重要的新特性。
为什么要使用lambda表达式?
- lambda允许将函数当作方法参数并传入,使代码变得更加简洁、紧凑。
- lambda表达式免去了使用匿名方法的麻烦,并且给予java简单又强大的函数化编程能力。
语法
lambda表达式的语法格式:
(parameter) -> expression 或 (parameter) -> {statements;}
特征:
- 可选类型声明:可以不用参数类型,编译器可自动识别参数类型。
(int a) -> System.out.println(a)
或
(a) -> System.put.println(a)
- 可选的参数圆括号:一个参数时可以不用定义圆括号,但多个参数需要定义圆括号。
a-> System.out.println(a)
(a,b) -> a+b
- 可选大括号:当主体只包含一条语句,则不需要使用大括号。
(a,b) -> a+b
(a,b) -> {
return a+b;
}
- 可选的返回关键字: 当主体只有一个表达式时自动返回值,多个表达式需要使用大括号则代表需要手动使用return关键字进行值的返回。
(a,b) -> a+b
(a,b) -> {
int sum = a+b;
int result = sum/10;
return result;
}
实例
public class Test {
public static void main(String[] args) {
//MyFunctionInterface1 myFunctionInterface1 = (int a,int b) -> a + b;
MyFunctionInterface1 myFunctionInterface1 = (a,b) -> a + b;
System.out.println(myFunctionInterface1.addition(5, 3));
//MyFunctionInterface2 myFunctionInterface2 = String msg -> System.out.println(msg);
MyFunctionInterface2 myFunctionInterface2 = msg -> System.out.println(msg);
Test test = new Test();
System.out.println(test.operate(1,1,myFunctionInterface1));
}
private int operate(int a, int b, MyFunctionInterface1 mf) {
return mf.addition(a, b);
}
}
@FunctionalInterface
interface MyFunctionInterface1 {
int addition(int a,int b);
}
@FunctionalInterface
interface MyFunctionInterface2 {
void addition(String msg);
}
3、变量作用域
lambda表达式中之只能引用标记了final的外层局部变量,这就是说不能再lambda表达式内部修改定义在域外的局部变量,否则会编译错误。
public class Test {
public static void main(String[] args) {
int num = 10;
//报错信息:Local variable num defined in an enclosing scope must be final or effectively final
MyFunctionInterface1 myFunctionInterface1 = (a,b) -> a + b + num;
System.out.println(myFunctionInterface1.addition(5, 3));
num = 50;
}
}
@FunctionalInterface
interface MyFunctionInterface1 {
int addition(int a,int b);
}
正确写法:
public class Test {
public static void main(String[] args) {
final int num = 10;
MyFunctionInterface1 myFunctionInterface1 = (a,b) -> a + b + num;
System.out.println(myFunctionInterface1.addition(5, 3)); //输出结果为18
}
}
...省略
>>> Java8-11新特性总结(二)
>>> Java8-11新特性总结(四)