Java8 @FunctionalInterface

写了很久的java8,也使用过函数式接口,但是一直云里雾里的,最近在接触过python/js/c++后比较明朗了。

假定我们有这样一个场景:给定两个数,在不同的处理流程中,有时候计算和,有时候又需要计算差,我们希望在计算的时候,要做好参数校验

在python中我们可以这样处理:

def sum(a, b):
    return a + b


def sub(a, b):
    return a - b


def math_calculate(a, b, func):
    # 做一些公共的逻辑处理,比如参数校验
    if a is None or b is None:
        return None

    return func(a, b)


sum_result = math_calculate(100, 20, sum)
print(sum_result)

sub_result = math_calculate(100, 20, sub)
print(sub_result)

 运行该python脚本,输出结果是:120, 80

math_calculate函数的第三个参数,传递的是一个函数名,那么在进行func(a,b)的时候,实际上就是执行传递的函数逻辑。比如我传递的是sum,那么math_calculate函数实际上执行的是sum(a,b)。

math_calculate函数的好处是,把参数的校验统一起来了,不用分散到sum和sub这两个函数中。

在c/c++中我们可以定义函数指针,逻辑类似。

但是在java中呢,却不能给方法传递方法名。我们通常的做法是定义一个抽象类/接口,然后子类实现其中的方法,来实现,比如:

public abstract class MathCalculate {

    protected abstract Integer calculate(Integer a, Integer b);
}


public class SumMathCalculate extends MathCalculate {

    @Override
    protected Integer calculate(Integer a, Integer b) {
        return a + b;
    }
}


public class SubMathCalculate extends MathCalculate {

    @Override
    protected Integer calculate(Integer a, Integer b) {
        return a - b;
    }
}

public class Test {
    public static Integer mathCalculate(Integer a, Integer b, MathCalculate calculateImpl) {
        if (null == a || b == null) {
            return null;
        }
        return calculateImpl.calculate(a, b);
    }

    public static void main(String[] args) {

        SumMathCalculate sum = new SumMathCalculate();

        SubMathCalculate sub = new SubMathCalculate();

        mathCalculate(100, 20, sum);
        mathCalculate(100, 20, sub);

    }
}

在Test类中的mathCalculate第三个参数,传递的是对象。

表面上看这样实现,为了一个简单的计算逻辑,还得定义三个类,然后串起来,有点"太重了"的感觉。其实我们只要对象中的函数,不希望有对象!

Java8函数式接口,就是来优化这一点的!

@FunctionalInterface
interface MathCalculate2 {
    Integer calculate(Integer a, Integer b);
}

public class Test2 {
    public static Integer mathCalculate(Integer a, Integer b, MathCalculate2 calculateFunc) {
        if (null == a || b == null) {
            return null;
        }
        return calculateFunc.calculate(a, b);
    }

    public static void main(String[] args) {
        mathCalculate(100, 20, (a, b) -> a + b);
        mathCalculate(100, 20, (a, b) -> a - b);
    }

}

注意,此时MathCalculate2,加了@FunctionalInterface,表明是一个函数式接口,不再希望像通常使用接口的方式来使用,而是要传入一个lamda表达式(也就是函数的真正实现)。

这样下次如果需要乘法和除法,或者其他的二目运算,那么只需要传递函数实现就是了,不需要定义类了!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值