• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

JDK8新特性之函数式接口

技术杂谈 勤劳的小蚂蚁 2个月前 (02-16) 63次浏览 已收录 0个评论 扫描二维码


什么是函数式接口

先来看看传统的创建线程是怎么写的
  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. }


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:JDK8新特性之函数式接口
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00