什么是函数式接口
函数式接口是Java8引用的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method)。但是它还是一个接口,只是有些特殊罢了。 函数式接口的出现主要是为了配合Java8的另一个新特性Lamdba表达式来使用。
- 接口中只有一个抽象方法
- 接口中面可以加一个注解*@FunctionalInterface*来检查接口中的方法是不是只有一个抽象方法
- 在接口里面可以加入 默认方法 和 静态方法
- 函数式接口也可以继承,但是继承的时候,抽象方法必须一样
- 函数式接口重写父类的的方法,并不会计入到自己的抽象方法中
自定义函数式接口
1//加入这个注解是为了检测接口中是否符合函数式接口的要求 2@FunctionalInterface 3public interface MyFunctionInterction { 4 //唯一的抽象方法 5 void absoluMethod(); 6 7 //重写Object的方法 8 @Override 9 String toString(); 10 11 //默认方法 12 default void defaultMethod() { 13 System.out.println("默认方法"); 14 } 15 16 //静态方法 17 static void stativMethod() { 18 System.out.println("静态方法"); 19 } 20}
函数式接口的简单使用
1里面的默认方法可以直接使用 2 3 4public class TestFunctionIntection { 5 public static void main(String[] args) { 6 TestFunctionIntection testFunctionIntection = 7 new TestFunctionIntection(); 8 testFunctionIntection.test( 9 //Lamdba表达式的简单使用 10 () -> System.out.println("函数式接口里面的抽象方法")); 11 } 12 13 /** 14 * 自己定义的一个方法,并使用自定义的一个消费类型的函数式接口 15 * @param myFunctionInterction 16 */ 17 public void test(MyFunctionInterction 18 myFunctionInterction) { 19 20 //函数式接口里面的抽象方法 21 myFunctionInterction.absoluMethod(); 22 23 //默认方法 24 myFunctionInterction.defaultMethod(); 25 26 //静态方法 27 MyFunctionInterction.stativMethod(); 28 } 29}
java8里面自定义的四个核心的函数式接口
上面我自定义的一个接口,就是一个消费类型的函数式接口。其实这类接口在_java.util.function_里面有定义的,就是void Consumer< T >,消费类型接口,上面代码中的test方法里面的接口其实可以换成Consumer< T >接口,也可以用,下面主要就是介绍这四个函数式接口的简单使用。

下面是这四个核心接口的简单使用
1public class FunctionTest { 2 //Consumer<T> 消费型接口 3 @Test 4 public void test1() { 5 Consumer<String> consumer = (x) -> System.out.println(x); 6 consumer.accept("消费型接口,没有返回值!"); 7 } 8 //输出:消费型接口,没有返回值! 9 10 //供给型接口 11 @Test 12 public void test2() { 13 Supplier<String> supplier = () -> "主要的作用就是创建对象!"; 14 String s = supplier.get(); 15 System.out.println(s); 16 } 17 //输出:主要的作用就是创建对象! 18 19 //函数型接口 20 //Function<T,R> T 接收的参数,R 返回值类型 21 @Test 22 public void test3() { 23 Function<Integer, String> function = (x) -> x + ":为String类型"; 24 String apply = function.apply(7); 25 System.out.println(apply); 26 } 27 //输出:7:为String类型 28 29 //断言型接口 30 @Test 31 public void test4() { 32 Predicate<Integer> predicate = (x) -> x > 10; 33 boolean test = predicate.test(11); 34 System.out.println(test); 35 } 36 //输出:true 37}
Consumer<T> 的应用
1//Consumer<T> 消费型接口 2 @Test 3 public void test1() { 4 //定义一个消费型接口,只输出输入的内容 5 Consumer<String> consumer = (x) -> System.out.println(x); 6 //在输入的内容后面加上·--加上了默认方法· 7 Consumer<String> consumer2 = (x) -> System.out.println(x + "--加上了默认方法"); 8 //执行顺序 先执行 accept 后面执行 addThen(然后) 9 consumer.andThen(consumer2).accept("消费型接口,没有返回值!"); 10 } 11 //输出:消费型接口,没有返回值 (accept输出的值) 12 //输出:消费型接口,没有返回值 !--加上了默认方法 (addThen输出的值)
Consumer<T> 的默认方法的源码:
1default Consumer<T> andThen(Consumer<? super T> after) { 2 Objects.requireNonNull(after); 3 return (T t) -> { accept(t); after.accept(t); }; 4}
其返回值这一句是重点,先是传入一个Consumer接口,然后返回一个Consumer接口,说明可以用表达式链,然后用这个特性可以把数据进一次进行加工。 (T t) -> { accept(t); after.accept(t); };这一句,返回的顺序首先是调用抽象方法,然后再调用默认方法,说明这个默认方法只可以对数据进行再加工,不能再抽象方法前面。
<hr>Supplier<T> 的应用
1 //供给型接口,这个方法若以用在工厂方法中 2 @Test 3 public void test2() { 4 //跟据一个字符串创建对象 5 Supplier<String> supplier = () -> "主要的作用就是创建对象!"; 6 //获取一个对象 7 String s = supplier.get(); 8 //获取两个以象 9 String s1 = supplier.get(); 10 //两个对象内容一样 11 System.out.println(s.equals(s1)); 12 System.out.println(s); 13 //用方法引用的方式创建一个对象 14 Supplier<SupplierTest> testSupplier = SupplierTest::new; 15 //用new的方式创建一个对象 16 Supplier<SupplierTest> supplierTestSupplier = () -> new SupplierTest("张三"); 17 //可以通过supplierTestSupplier 来获取一个对象,并且可以调用里面的方法 18 String name = supplierTestSupplier.get().getName(); 19 System.out.println(name); 20 } 21 //输出:true 22 //输出:主要的作用就是创建对象! 23 //输出:张三
Supplier< T >接口类型就有一个方法签名。T get()方法,没有默认方法。 <hr>
Function< T,R > 的应用
1//默认主法addThen 2//函数型接口 3 //Function<T,R> T 接收的参数,R 返回值类型 4 @Test 5 public void test3() { 6 Function<String, String> f1 = (x) -> x +"+ "; 7 Function<String, String> f2 = (x) -> x + "- "; 8 //addThen(然后的意思)执行顺序先执行f1,并且把执行后的结果作为f2的输入参数 9 String apply = f1.andThen(f2).apply("1"); 10 System.out.println(apply); 11 } 12 //输出:1+ -
addThen的源码:
1default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { 2 Objects.requireNonNull(before); 3 return (V v) -> apply(before.apply(v)); 4}
源码中最重要的一句
(V v) -> apply(before.apply(v)); 规定了执行顺序
1 //默认主法compose 2 //函数型接口 3 //Function<T,R> T 接收的参数,R 返回值类型 4 @Test 5 public void test3() { 6 Function<String, String> f1 = (x) -> x +"+ "; 7 Function<String, String> f2 = (x) -> x + "- "; 8 //addThen(然后的意思)执行顺序先执行f2,并且把执行后的结果作为f1的输入参数 9 String apply = f1.compose(f2).apply("1"); 10 System.out.println(apply); 11 } 12 //输出:1- +
三个默认方法,但是最后一个用的不多,这里也就不再介绍了。
<hr>Predicate< T > 的应用
1//默主方法negate 非 2//断言型接口 3 @Test 4 public void test4() { 5 Predicate<Integer> predicate = (x) -> x > 10; 6 boolean test = predicate.negate().test(11); 7 System.out.println(test); 8 } 9 //输出:false 10 11 12 //断言型接口 13 //默认方法 or 和 and 14 @Test 15 public void test4() { 16 Predicate<Integer> p1 = (x) -> x > 10; 17 Predicate<Integer> p2 = (x) -> x < 5; 18 //默认方法 or 或 19 boolean test = p1.or(p2).test(3); 20 //默认方法 and 且 21 boolean test2 = p1.and(p2).test(3); 22 23 System.out.println(test); 24 System.out.println(test2); 25 } 26 //输出:true 27 //输出:false 28
函数式接口的使用
函数式接口的的使用,大部分都是在流操作里面进行,现在可以不太理解,但是可以在学习完流操作以后,再过来看,并且跟着写一遍。代码光看是没有用的。如果不写是不知道意思的。
参考的博客:浅浅的函数式接口
<br> <hr> <center>
细节决定成败! 个人愚见,如有不对,恳请扶正!
</center>