Lambda表达式和函数式接口
在Java8以前,我们想要让一个方法可以与用户进行交互,比如说使用方法内的局部变量;这时候就只能使用接口做为参数,让用户实现这个接口或使用匿名内部类的形式,把局部变量通过接口方法传给用户。
传统匿名内部类缺点:代码臃肿,难以阅读
Lambda表达式
Lambda表达式将函数当成参数传递给某个方法,或者把代码本身当作数据处理;
语法格式:
- 用逗号分隔的参数列表
- ->符号
- 和语句块组成
Lambda本质上是匿名内部类的改装,所以它使用到的变量都会隐式的转成final 的
String separator = ",";
Arrays.asList("a","b","c").forEach(e-> System.out.println(e+separator));
separator = separator + ".";//会报错 java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
函数式接口
- 接口中只能有一个接口方法
- 可以有静态方法和默认方法
- 使用@Functionallnterface标记
- 默认方法可以被覆写
已经存在的Java8定义的函数式接口:
1.Function<T, R> 函数型接口
接受一个输入参数T,返回一个结果R。
public class TestFunction {
public static void main(String[] args) {
int num = 10;
int result1 = plusTwo(num, x -> x + 5);
System.out.println("经过plusTwo后的结果:" + result1);
int result2 = before(num, x -> x + 5, x -> x * x);
System.out.println("经过before后的结果:" + result2);
int result3 = after(num, x -> x + 5, x -> x * x);
System.out.println("经过after后的结果:" + result3);
}
private static Integer plusTwo(int origen, Function<Integer, Integer> function) {
return function.apply(origen);
}
private static Integer before(int origen, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
// origen作为function2的参数,返回一个结果,该结果作为function1的参数,返回一个最终结果
return function1.compose(function2).apply(origen);
}
private static Integer after(int origen, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
// origen作为function1的参数,返回一个结果,该结果作为function2的参数,返回一个最终结果
return function1.andThen(function2).apply(origen);
}
}
控制台结果:
经过plusTwo后的结果:15
经过before后的结果:105
经过after后的结果:225
2.Predicate 断言型接口
接受一个输入参数T,返回一个布尔值结果
public class TestPredicate {
public static void main(String[] args) {
int num = 10;
boolean result = judge(num, x -> x >= 10);
System.out.println("经过judge后结果:" + result);
}
private static boolean judge(int num, Predicate<Integer> predicate) {
return predicate.test(num);
}
}
控制台结果:
经过judge后结果:true
3.Supplier 供给型接口
无输入参数,返回一个结果T。
public class TestSupplier {
public static void main(String[] args) {
Supplier supplier = ()->{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
return sdf.format(date);
};
System.out.println("当前系统时间为;"+supplier.get());
}
}
控制台结果:
当前系统时间为;2022-04-18 14:19:10
4.Consumer 消费型接口
接受一个输入参数并且无返回值。
public class TestConsumer {
public static void main(String[] args) {
Consumer<Integer> consumer = x -> System.out.println("输入值加上10的结果为:" + (x + 10));
consumer.accept(990);
}
}
控制台结果为:
输入值加上10的结果为:1000