前言
接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Lambda 表达式和函数式接口说明。
Lambda 表达式
lambda 表达式其实就是使用了新的语法结构来实现一个接口,并实现里面的唯一的一个方法,用来代替以前的使用匿名内部类的方式。
// x 指参数列表 -> 后面表示处理过程,Consumer 没有返回值
Consumer out = x -> System.out.println(x);
// x,y 指参数列表 -> 后面表示处理过程和返回值
BinaryOperator<Integer> binaryOperator = (x,y) -> {return x > y ? 1 : -1 ;};
函数式接口
根据上面来看,其实就是实现了接口中的一个方法,所以这种接口有一个限制,只能有一个方法,像这样的接口就叫函数式接口,你也可以当成正常的接口来使用。
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String o) {System.out.println(o);
}
};
常用的函数式接口
我们基本不需要定义自己的函数式接口,Java8 已经给我们提供了大量的默认函数式接口,基本够用,在 rt.jar
包的 java.util.function
目录下可以看到所有默认的函数式接口,大致分为几类
-
Function<T,R>
T 作为输入,返回的 R 作为输出 -
Predicate<T>
T 作为输入,返回 boolean 值的输出 -
Consumer<T>
T 作为输入,没有输出 -
Supplier<R>
没有输入 , R 作为输出 -
BinaryOperator<T>
两个 T 作为输入,T 同样是输出 -
UnaryOperator<T>
是Function
的变种,输入输出者是 T
其它的都是上面几种的各种扩展,只为更方便的使用,下面演示示例,你可以把其当成正常的接口使用,由用户使用 Lambda 来实现。
// hello world 示例
Function<String,String> function = (x) -> {return x+"Function";};
System.out.println(function.apply("hello world")); // hello world Function
UnaryOperator<String> unaryOperator = x -> x + 2;
System.out.println(unaryOperator.apply("9420-")); // 9420-2
// 判断输入值是否为偶数示例
Predicate<Integer> predicate = (x) ->{return x % 2 == 0 ;};
System.out.println(predicate.test(1)); // false
// 这个没有返回值
Consumer<String> consumer = (x) -> {System.out.println(x);};
consumer.accept("hello world"); // hello world
// 这个没有输入
Supplier<String> supplier = () -> {return "Supplier";};
System.out.println(supplier.get()); // Supplier
// 找出大数
BinaryOperator<Integer> bina = (x, y) ->{return x > y ? x : y;};
bina.apply(1,2); // 2
方法引用
Supplier<DateTimeConvert> supplier = () -> new DateTimeConvert();
DateTimeConvert dateTimeConvert = supplier.get();
Consumer<DateTimeConvert> consumer1 = (x) -> x.toCalendar();
consumer1.accept(dateTimeConvert);
可能 java 的开发者觉得上面的操作还是太复杂了,又创建了一个语法 ::
来表示 Lambda 表达式
Supplier<DateTimeConvert> supplier2 = DateTimeConvert::new;
Consumer<DateTimeConvert> consumer2 = DateTimeConvert::toCalendar;