在使用Lambda表达式时,我们使用匿名函数的方式作为参数进行传递,如对员工按工资进行筛选,实际上是将 接口MyPredicate的test(T t) 方法进行了实现,如下:
参见Java8新特性(一)——Lambda表达式
public interface MyPredicate<T> {
boolean test(T t);
}
public List<Employee> filterEmployee(List<Employee> employees, MyPredicate<Employee> mp){
List<Employee> emps = new ArrayList<>();
for (Employee emp : employees) {
if (mp.test(emp)){
emps.add(emp);
}
}
return emps;
}
public void test4(){
List<Employee> employees = new TestLambda().filterEmployee(TestLambda.employees,
e -> e.getSalary() > 3000);
employees.forEach(System.out::println);
}
但是如果MyPredicate接口中的方法有多个,我们如何确定我们实现的方法是我们想要的方法呢?话不多说,试一试就知道!
public interface MyPredicate<T> {
boolean test(T t);
int test1(T t);
}
直接挂掉,Lambda表达式不能用了,编译器报错!!!不是因为Employe对象没有getSalary方法,而是因为MyPredicate接口有多个抽象方法,Lambda表达中实现的是哪个方法编译器根本不知道,所以Lambda表达式要求实现的接口只能有一个抽象方法!!!
如果有一种方式可以保证某个接口只能有一个抽象方法那是不是很nice呀!!!往下看
↓↓↓↓↓
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。
自定义函数式接口
@FunctionalInterface
public interface MyPredicate<T> {
boolean test(T t);
}
作为递 参数传递 Lambda
public void test4(){
List<Employee> employees = new TestLambda().filterEmployee(TestLambda.employees,
e -> e.getSalary() > 3000);
employees.forEach(System.out::println);
}
【注意】:作为递 参数传递 Lambda 将 表达式:为了将 Lambda 表达式作为参数传递,接收 Lambda 该 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。
可是每次使用Lambda表达式都需要手写一个函数式接口,就那么两行是不是有点烦?!
不要fang,Java中有内置的函数式接口供我们使用,继续往下看
↓↓↓↓↓
函数式接口 | 参数类型 | 返回值类型 | 用途 |
---|---|---|---|
Consumer消费型接口 | T | void | 对类型为T的对象应用操作,包含方法:void accept(T t); |
Supplier供给型接口 | 无 | T | 返回类型为T的对象,包含方法:T get(); |
Function |
T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t); |
Predicate断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法boolean test(T t); |
public void test1(){
consumer(1000,(m) -> System.out.println("老王此次消费:"+m+"元!"));
}
public void consumer(double money, Consumer<Double> con){
con.accept(money);
}
public void test2(){
List<Integer> list = supplier(10, () -> new Random().nextInt(10));
System.out.println(list);
}
public List<Integer> supplier(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>(num);
for (int i = 0; i < num; i++) {
list.add(sup.get());
}
return list;
}
public void test3(){
String str = function("are you ok?",s -> s.toUpperCase());
System.out.println(str);
}
public String function(String str, Function<String,String> fun){
return fun.apply(str);
}
public void test4(){
List<String> list = Arrays.asList("hello","ok","python","java","javascript");
List<String> strings = predicate(list, s -> s.length() > 4);
System.out.println(strings);
}
public List<String> predicate(List<String> stringList, Predicate<String> pre){
List<String> list = new ArrayList<>();
for (String s : stringList) {
if (pre.test(s)){
list.add(s);
}
}
return list;
}
测试主函数及结果
public static void main(String[] args){
//消费型函数式接口
new TestFunction().test1();
System.out.println("==========================================================");
//供给型函数式接口
new TestFunction().test2();
System.out.println("==========================================================");
//函数型函数式接口
new TestFunction().test3();
System.out.println("==========================================================");
//函数型函数式接口
new TestFunction().test4();
}
还有许多Java提供的函数式接口可以供我们使用,不太能记得住,可以参见如下链接:
Java 8 函数式接口|菜鸟教程
注:菜鸟一枚,才疏学浅,希望各位前辈能够批评指正,感谢感谢!!!