函数式接口理解

函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

一、自定义

在自定义接口前,我们要先认识一下@FunctionalInterface注解:

  • @FunctionalInterface注解只能标注一个接口,不能标注,方法,枚举,属性等。
  • 如果接口被标注了@FunctionalInterface,这个类就必须符合函数式接口的规范
  • 即使一个接口没有标注@FunctionalInterface,如果这个接口满足函数式接口规则,依旧被当作函数式接口。

根据最上文的定义,我们能非常直白的理解什么是函数式接口的规则。(1)有且只有一个抽象方法。(2)可以有很多非抽象的方法,当然根据jdk1.8的新特性,接口中的非抽象方法需要用default修饰。下面我们自定义一个函数式接口:

@FunctionalInterface
public interface Square {
    int square(int x);
    defalut int compute(int x){
        System.out.println(square(x));
    }
}

public class FunctionalInterfaceTest{
    public static void test(int x, Square square){
        square.compute(x);
    }    
    public static void main(String[] args){
        
        int a=10;
        Square square = (x) -> x * x;
        test(a,square);
        // 或者直接写成
        int a=10;
        test(a,(x) -> x * x)
        
    }
}

上面是一个非常简单的例子,自定义了一个接口Square,抽象函数square求平方,compute打印计算结果。

二、官方接口

java.util.function包中为我们提供了43种函数式接口,调用起来非常方便。因此,很多情况下,我们不需要自己去定义函数式接口。

nametypedescription
ConsumerConsumer< T >接收T对象,不返回值
PredicatePredicate< T >接收T对象并返回boolean
FunctionFunction< T, R >接收T对象,返回R对象
SupplierSupplier< T >提供T对象(例如工厂),不接收值
UnaryOperatorUnaryOperator接收T对象,返回T对象
BinaryOperatorBinaryOperator接收两个T对象,返回T对象

上表为java.util.function中的部分接口,我们采用Function< T, R >模板举个例子: 

public class FunctionTest{
    public static Integer compute(Integer x,Function<Integer,Integer> function){
        Integer re = function.apply(x)
        System.out.println(re);
        return re;
    }   
    public static void main(String[] args){
        int x = 10;
        // 平方
        compute(x,y->y*y);
        // 加倍
        compute(x,y->y+y);
    }
}

三、什么时候需要自定义函数式接口(引用于Effective java 第44条)

1、只要标准的函数接口能够满足需求,通常应该优先考虑,而不是专门再构建一个新的函数接口 。 这样会使 API 更加容易学习,通过减少它的概念内容,显著提升互操作性优势,因为许多标准的函数接口都提供了有用的默认方法 。

2、如果你所需要的函数接口与 Comparator 一样具有一项或者多项以下特征, 则必须认真考虑自己编写专用的函数接口,而不是使用标准的函数接口 :
(1) 通用,并且将受益于描述性的名称 。
(2) 具有与其关联的严格的契约 。
(3) 将受益于定制的缺省方法 。

以 Comparator< T>为例 , 它与 TointBiFunction<T , T>接口在结构上一致,虽然前者被添加到类库中时,后一个接口已经存在,但如果用后者就错了 。 Comparator 之所以需要有自己的接口,有三个原因 。 首先,每当在 API 中使用时,其名称提供了良好的文档信息,并且被大量使用 。 其次, Comparator 接口对于如何构成一个有效的实例,有着严格的条件限制,这构成了它的总则( general contract ) 。 实现该接口相当于承诺遵守其契约 。 第三 ,这个接口配置了大量很好用的缺省方法,可以对比较器进行转换和合并 。
 

 

 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值