- 相关类:
Supplier
、Consumer
、Predicate
、Function
-
什么是函数式接口
- 有且只有一个抽象方法的接口被称作函数式接口
- 函数式接口可以直接写成Lambda表达式
- 函数式接口还可以写成方法引用的方式
- 函数式接口对外展示的是一个规范,只需要满足这种规范即可成为其实现
- 函数式接口可以类比为多态在函数式结构上的实现
package com.yusian.function; import java.util.function.Supplier; /** * Supplier是一个函数式接口,返回任意类型数据,是一个容器 * 他是对所有无参并返回一个对象的结构抽象,一切无参并返回对象的方法都可以成为他的实现 * 这使得编程变得更加开放,可以想像是多态在函数式编程方式上的实现 */ public class SupplierDemo { public static void main(String[] args) { // 1、匿名内部类 Supplier<Person> sup1 = new Supplier<Person>() { @Override public Person get() { return new Person(); } }; Person p1 = sup1.get(); // 2、Lambda表达式 Supplier<Person> sup2 = () -> new Person(); Person p2 = sup2.get(); // 3、方法引用 Supplier<Person> sup3 = Person::new; Person p3 = sup3.get(); // 4、本地方法模拟 Person p4 = supplier(); // 5、只要满足函数式结构就可以 Supplier<Person> sup5 = SupplierDemo::supplier; Person p5 = sup5.get(); System.out.println(p1); System.out.println(p2); System.out.println(p3); System.out.println(p4); System.out.println(p5); } /** * 获取一个Person实例对象 * @return Person */ public static Person supplier() { return new Person(); } }
- 内置函数式接口的应用
Supplier
:提供者,该接口返回一个对象,以任何方式及任何身份返回一个对象,只要是无参数返回一个对象的任何方法都可以成为其实现;-
Consumer
:消费者,传入一个对象无返回值,提供一个对象,可以是任何形式的调用,“尽情消费”;Consumer
中有一个andThen
方法,这个方法会返回一个Consumer
,有点绕package com.yusian.function; import java.util.function.Consumer; public class ConsumerDemo { public static void main(String[] args) { /* * 输出结果为: * Hello World * Hello World-1 * Hello World-2 */ Consumer<String> con = System.out::println; con.andThen(str -> { System.out.println(str + "-1"); }).andThen(str -> { System.out.println(str + "-2"); }).accept("Hello World"); /* * 换个形式来解释: * con1调用andThen方法,con2为参数得到的结果是一个Consumer * 得到的这个Consumer即不是con1也不是con2,是一个会先执行con1的accept方法再执行con2的 * accept方法的Consumer * 可以简单的理解为返回的这个Consumer中accept方法是将con1和con2的accept方法按先后顺序 * 调用 * 同理:再调用andThen方法是新这个新的Consumer调用的,再将con3拉进来返回一个新的 * Consumer * 从表面上看一共是定义了4个Consumer,现实上一共出现的Consumer有7个,每调用一次andThen * 都会生成一个新的Consumer */ Consumer<String> con1 = str -> System.out.println(str + "-1"); Consumer<String> con2 = str -> System.out.println(str + "-2"); Consumer<String> con3 = str -> System.out.println(str + "-3"); Consumer<String> con4 = str -> System.out.println(str + "-4"); con1.andThen(con2).andThen(con3).andThen(con4).accept("Java"); } } ``` 执行结果: ```cmd Hello World Hello World-1 Hello World-2 Java-1 Java-2 Java-3 Java-4
Predicate
:断言,用于对传入对象的boolean判断,给你一个对象,你告诉我是否;package com.yusian.function; import java.util.ArrayList; import java.util.function.Predicate; public class PredicateDemo { public static void main(String[] args) { demo01(); } // 过滤字符串数组中的特定元素,2个过滤条件可以通过2个Predicate实现 private static void demo01() { // 过滤数组 String[] array = {"xxxx,女", "yyyy,女", "zzzz,男", "xxx,女"}; ArrayList<String> list = new ArrayList<>(); Predicate<String> pre1 = str -> str.split(",")[0].length() == 4; Predicate<String> pre2 = str -> str.split(",")[1].equals("女"); for (String s : array) { if (filter(s, pre1, pre2)) list.add(s); } System.out.println(list); } private static boolean filter(String str, Predicate<String> pre1, Predicate<String> pre2) { return pre1.and(pre2).test(str); } private static void basic() { Predicate<String> pre1 = str -> str.endsWith("s"); Predicate<String> pre2 = str -> str.length() > 3; boolean b1 = pre1.test("yes"); System.out.println(b1); // or方法返回的是一个新的Predicate,这个Predicate将前一个Predicate与传入的这个Predicate中的两个test方法进行或运算 boolean b2 = pre1.or(pre2).test("think"); System.out.println(b2); // and方法返回的是一个新的Predicate,这个Predicate将前一个Predicate与传入的这个Predicate中的两个test方法进行与运算 boolean b3 = pre1.and(pre2).test("this"); System.out.println(b3); // negate方法返回一个新的Predicate,这个Predicate的test方法是对调用者的test方法取反 boolean b4 = pre1.negate().test("yes"); System.out.println(b4); // equal方法只是简单的==运算,可能是为了充实这个接口的功能吧 boolean b5 = pre1.equals(pre2); System.out.println(b5); } }
Function
:功能package com.yusian.function; import java.util.function.Function; public class FunctionDemo { public static void main(String[] args) { // 将字符串拼接"10"再转成数字 Function<String, Integer> fun1 = str -> Integer.parseInt(str + "10"); // 将数字+10再转成字符串 Function<Integer, String> fun2 = n -> String.valueOf(n + 10); // andThen会执行前面的Function的apply,所以是12310+10 数字12320 String ret1 = fun1.andThen(fun2).apply("123"); System.out.println(ret1); // compose会先执行后面Function的apply,所以是133拼接"10" 字符串13310 Integer ret2 = fun1.compose(fun2).apply(123); System.out.println(ret2); } }