Java8新特性(二)——函数式接口

mac2024-06-04  54

二、函数式接口

1.思考问题

在使用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呀!!!往下看 ↓↓↓↓↓

2. Lambda表达式需要“函数式接口”支持

函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。

可以通过 Lambda 表达式来创建该接口的对象我们可以在任意函数式接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。

自定义函数式接口

@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中有内置的函数式接口供我们使用,继续往下看 ↓↓↓↓↓

3.Java 内置四大核心函数式接口

函数式接口参数类型返回值类型用途Consumer消费型接口Tvoid对类型为T的对象应用操作,包含方法:void accept(T t);Supplier供给型接口无T返回类型为T的对象,包含方法:T get();Function<T, R>函数型接口TR对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t);Predicate断定型接口Tboolean确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法boolean test(T t); Consumer消费型接口` public void test1(){ consumer(1000,(m) -> System.out.println("老王此次消费:"+m+"元!")); } public void consumer(double money, Consumer<Double> con){ con.accept(money); } Supplier供给型接口 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; } Function<T, R>函数型接口 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); } Predicate断定型接口 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(); }

3.其他接口

还有许多Java提供的函数式接口可以供我们使用,不太能记得住,可以参见如下链接:

Java 8 函数式接口|菜鸟教程

注:菜鸟一枚,才疏学浅,希望各位前辈能够批评指正,感谢感谢!!!

最新回复(0)