最新公告
  • 欢迎您光临极客文库,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们

  • 什么是函数式接口

    先来看看传统的创建线程是怎么写的
    1. Thread t1 =newThread(newRunnable(){
    2.    @Override
    3.    publicvoid run(){
    4.        System.out.println("t1");
    5.    }
    6. });
    7. t1.start();
    再来看看使用了函数式接口是怎么写的
    1. Thread t2 =newThread(()->System.out.println("t2"));
    2. t2.start();
    Runnable接口直接可以使用Lambda表达式来编写,这是因为Runnable接口是一个函数式接口,来看看Runnable的源码。
    1. @FunctionalInterface
    2. publicinterfaceRunnable{
    3.    publicabstractvoid run();
    4. }
    发现该接口加上了函数式接口的定义注解: @FunctionalInterface,表明该接口是一个函数式接口。
    1. @Documented
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Target(ElementType.TYPE)
    4. public@interfaceFunctionalInterface{
    5. }
    在JDK8中,除了Runnbale接口,还有像Comparator、Callable等接口都加上了该注解定义为函数式接口。

    内置函数式接口

    JDK8提供了几个内置的函数式接口,用在了许多API的地方,都可以拿来用,可以满足大部分应用。
    1. //Consumer<T> - T作为输入,执行某种动作但没有返回值
    2. Consumer<String> con =(x)->{
    3.    System.out.println(x);
    4. };
    5. con.accept("hello world");
    6. //Supplier<T> - 没有任何输入,返回T
    7. Supplier<String> supp =()->{
    8.    return"Supplier";
    9. };
    10. System.out.println(supp.get());
    11. //Predicate<T> -T作为输入,返回的boolean值作为输出
    12. Predicate<String> pre =(x)->{
    13.    System.out.print(x);
    14.    return x.startsWith("op");
    15. };
    16. System.out.println(": "+ pre.test("op, hello World"));
    17. // Function<T, R> -T作为输入,返回的R作为输出
    18. Function<String,String>function=(x)->{
    19.    System.out.print(x +": ");
    20.    return"Function";
    21. };
    22. System.out.println(function.apply("hello world"));
    23. //BinaryOperator<T> -两个T作为输入,返回一个T作为输出,对于“reduce”操作很有用
    24. BinaryOperator<String> bina =(x, y)->{
    25.    System.out.print(x +" "+ y);
    26.    return"BinaryOperator";
    27. };
    28. System.out.println("  "+ bina.apply("hello ","world"));

    自定义函数式接口

    1、自定义一个函数式接口

    1. @FunctionalInterface
    2. publicinterfaceCalcInterface<N, V>{    
    3.    V operation(N n1, N n2);
    4. }
    这里只有一个抽象方法,@FunctionalInterface注解可以不用写,至于为什么可以往下看。

    2、新建一个引用函数式接口的类

    1. publicstaticclassNumberOperation<N extendsNumber, V extendsNumber>{
    2.    private N n1;
    3.    private N n2;
    4.    publicNumberOperation(N n1, N n2){
    5.        this.n1 = n1;
    6.        this.n2 = n2;
    7.    }
    8.    public V calc(CalcInterface<N, V> ci){
    9.        V v = ci.operation(n1, n2);
    10.        return v;
    11.    }
    12. }

    3、测试函数式接口

    1. privatestaticvoid testOperationFnInterface(){
    2.        NumberOperation<Integer,Integer> np =newNumberOperation(13,10);
    3.    CalcInterface<Integer,Integer> addOper1 =(n1, n2)->{
    4.        return n1 + n2;
    5.    };
    6.    CalcInterface<Integer,Integer> multiOper1 =(n1, n2)->{
    7.        return n1 * n2;
    8.    };
    9.    System.out.println(np.calc1(addOper1));
    10.    System.out.println(np.calc1(multiOper1));
    11.    // 上面的可以简写为
    12.    System.out.println(np.calc1((n1, n2)-> n1 + n2));
    13.    System.out.println(np.calc1((n1, n2)-> n1 * n2));
    14. }
    最后输出:
    1. 23
    2. 130
    3. 23
    4. 130

    函数式接口规范

    1、@FunctionalInterface标识为一个函数式接口只能用在只有一个抽象方法的接口上。
    2、接口中的静态方法、默认方法、覆盖了Object类的方法都不算抽象方法。
    3、@FunctionalInterface注解不是必须的,如果该接口只有一个抽象方法可以不写,它默认就符合函数式接口,但建议都写上该注解,编译器会检查该接口是否符合函数式接口的规范。

    举例说明

    正确的函数式接口。
    1. @FunctionalInterface
    2. publicinterfaceCalcInterface<N, V>{    
    3.    V operation(N n1, N n2);
    4. }
    加了几个符合函数式的方法也没事,编译器也不会报错。
    1. @FunctionalInterface
    2. publicinterfaceCalcInterface<N, V>{        
    3.    V operation(N n1, N n2);
    4.    publicboolean equals(Objectobject);
    5.    publicdefaultvoid defaultMethod(){
    6.    }
    7.    publicstaticvoid staticMethod(){
    8.    }
    9. }
    这个没用@FunctionalInterface函数式接口,有两个抽象方法,不能用于Lambda表达式。
    1. publicinterfaceCalcInterface<N, V>{    
    2.    V operation(N n1, N n2);
    3.    V operation2(N n1, N n2);
    4. }
    这个有两个抽象方法的用@FunctionalInterface注解的函数式接口编译会报错。
    1. @FunctionalInterface
    2. publicinterfaceCalcInterface<N, V>{    
    3.    V operation(N n1, N n2);
    4.    V operation2(N n1, N n2);
    5. }
    这个没有一个抽象方法,编译报错。
    1. publicinterfaceCalcInterface<N, V>{    
    2. }

    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » JDK8新特性之函数式接口

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    极客文库
    程序员的加油站

    Leave a Reply

    Hi, 如果你对这款模板有疑问,可以跟我联系哦!

    联系发布者

    Leave a Reply

    Hi, 如果你对这款模板有疑问,可以跟我联系哦!

    联系发布者
    • 99会员总数(位)
    • 3629资源总数(个)
    • 44本周发布(个)
    • 0 今日发布(个)
    • 105稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多