Java大家庭已经出到11版本了,我还在使用jdk7=-=,再不学就来不及了,所以赶紧学一下Java8的新特性。
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
函数式接口在java.util.function路径下。
在这个包中,每一个接口都被@FunctionalInterface标注,表示这个类是一个函数式接口,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。-- 摘录自菜鸟编程
这次我们简单粗暴一下,贴出测试代码,看下具体使用场景和用法吧
package com.example.demo; import com.example.demo.test.Car; import com.example.demo.test.PrintConsumer; import org.junit.Test; import java.util.Comparator; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.BiPredicate; import java.util.function.BinaryOperator; import java.util.function.BooleanSupplier; import java.util.function.Consumer; import java.util.function.DoubleToIntFunction; import java.util.function.Function; /** * @author JingQ at 2019/1/25 */ public class JDK8FunctionInterfaceTest { /** * BiConsumer<T, U>,接收两个参数,不返回结果(void) * * 输出:(说明函数内修改对象引用的话同时会修改对象的值) * 娃哈哈真好喝 * TEST */ @Test public void biConsumerTest() { BiConsumer<Car, String> biConsumer = (a, b) -> { System.out.println(a.getName() + b); a.setName("TEST"); }; Car car = new Car(); car.setName("娃哈哈"); biConsumer.accept(car, "真好喝"); System.out.println(car.getName()); } /** * BiFunction<T, U, R>, 接收两个参数<T, U>,返回R类型的结果 * 输出: * 0 - 相等 */ @Test public void biFunctionTest() { BiFunction<Integer, Integer, String> biFunction = (a, b) -> String.valueOf(a+b); System.out.println(biFunction.apply(1, 2).compareTo("3")); } /** * BinaryOperator<T> 用来接收两个T类型的参数,返回T类型的结果 */ @Test public void binaryOperatorTest() { // 比较两者的最大值 BinaryOperator<Integer> binaryOperator1 = BinaryOperator.maxBy(Comparator.naturalOrder()); System.out.println(binaryOperator1.apply(1, 2)); // 比较两者的最小值 BinaryOperator<Integer> binaryOperator2 = BinaryOperator.minBy(Comparator.naturalOrder()); System.out.println(binaryOperator2.apply(3, 4)); // 相加 BinaryOperator<Integer> add = (n1, n2) -> n1 + n2; System.out.println(add.apply(1, 3)); } /** * BiPredicate<T, U>,接收两个参数<T, U>,返回一个boolean类型结果 * 输出: * false */ @Test public void biPredicateTest() { BiPredicate<Integer, Integer> biPredicate = (a, b) -> a.equals(b); System.out.println(biPredicate.test(1, 3)); } /** * Boolean类型 提供者,用来获取一个Boolean值 * 如果只是用来返回true/false,感觉这个方法比较鸡肋;感觉可以使用statement,在返回结果前执行 */ @Test public void booleanSupplierTest() { BooleanSupplier booleanSupplier = () -> { System.out.println("Pre Action"); return Boolean.TRUE; }; System.out.println(booleanSupplier.getAsBoolean()); } /** * Consumer<T>,接受一个输入参数,返回空类型void * 还有一个andThen,可以用来实现责任链模式 * * 输出: * TEST * * NEXT TEST * Pre * End */ @Test public void consumerTest() { // 接受String类型的参数 Consumer<String> consumer = System.out::println; consumer.accept("TEST"); //空格预定 System.out.println(); // 责任链模式,可以设定下一个consumer // PrintConsumer.java // public void accept(String s) { // System.out.println("Pre"); // //xxx // System.out.println("End"); // } Consumer<String> nextConsumer = new PrintConsumer(); consumer.andThen(nextConsumer).accept("NEXT TEST"); } /** * DoubleToIntFunction 只有一个applyAsInt方法,接受double类型的参数,返回int类型的结果 */ @Test public void doubleToIntFunctionTest() { DoubleToIntFunction doubleToIntFunction = a -> (int) a; System.out.println(doubleToIntFunction.applyAsInt(10L)); } /** * Function<T, U>函数接口,接受T类型的参数,返回U类型的结果 * * compose和andThen这两个方法的区别在于执行方法的顺序问题 * * compose先执行后面函数,然后执行前面的函数;andThen先执行前面的函数,然后再执行后面的函数 */ @Test public void functionTest() { // 方法引用,Integer[类名]::valueOf[方法名](这个是静态方法引用) Function<String, Integer> function1 = Integer::valueOf; System.out.println(function1.apply("1010")); // 输出 1010 // andThen方法的入参类型为上一个方法的返回类型 Function<Integer, String> function2 = a -> { System.out.println("Pre Action : "); return String.valueOf(a) + "10"; }; System.out.println(function1.andThen(function2).apply("1010")); //输出 //Pre Action : //101010 // compose方法 Function<Integer, String> function3 = a -> { System.out.println(a); return a + "2020"; }; //compose先执行后面函数, 需要注意参数传递时调用的方法是否兼容,避免报错 System.out.println(function1.compose(function3).apply(10)); //输出 //10 //102020 } } 复制代码