Java8实战-总结13

Lambda表达式

数学中的类似思想

从另一个角度谈谈Lambda表达式和函数传递的思想。

积分

假设有一个(数学,不是Java)函数f,比如说定义是

	f(x) = x + 10

常见的一个问题就是,画在纸上之后函数下方的面积(把x轴作为基准)。如下图函数f(x) = x + 10,x37下方的面积:
在这里插入图片描述

在这个例子里,函数f是一条直线,因此很容易通过梯形方法(画几个三角形)来算出面积:

	1/2 × ((3 + 10) + (7 + 10)) × (7 - 3) = 60

那么这在Java里面如何表达呢?第一个问题是把积分号或dy/dx之类的换成熟悉的编程语言符号。
确实,根据第一条原则需要一个方法,比如说叫integrate,它接受三个参数:一个是f,还有上下限(这里是3.07.0)。于是写在Java里就是下面这个样子,函数f是被传递进去的:integrate(f, 3, 7)
请注意,不能简单地写:

	integrate(x + 10, 3, 7)

原因有二。第一,x的作用域不清楚;第二,这将会把x +10的值而不是函数E传给积分。事实上,数学上dx的秘密作用就是说“以x为自变量、结果是x+10的那个函数。”

与Java8的Lambda联系起来

前面说过,Java 8的表示法(double x) -> x + 10(一个Lambda表达式)恰恰就是为此设计的,因此你可以写:

	integrate((double x) -> x + 10, 3, 7)

或者

	integrate((double x) -> f(x), 3, 7)

或者,用前面说的方法引用,只要写:

	integrate(C::f, 3, 7)

这里c是包含静态方法f的一个类。理念就是把f背后的代码传给integrate方法。
现在可能在想如何写integrate本身了。还假设f是一个线性函数(直线)。可能会写成类似数学的形式:

	//错误的Java码!(函数的写法不能像数学里那样。)
	public double integrate((double -> double)f, double a, double b) {
		return (f(a) + f(b)) * (b - a) / 2.0;
	}

但因为Lambda表达式只能用于接受函数式接口的地方(这里就是Function),所以必须得写成这个样子:

	public double integrate(DoubleFunction<Double> f, double a, double b) {
		return (f.apply(a) + f.apply(b)) * (b - a) / 2.0;
	}

顺便提一句,有点儿可惜的是必须写f.apply(a),而不是像数学里面写f(a),但Java无法摆脱“一切都是对象”的思想——它不能让函数完全独立。

小结

以下是关键的概念。

  • Lambda表达式可以理解为一种匿名函数:它没有名称,但有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常的列表。
  • Lambda表达式让你可以简洁地传递代码。
  • 函数式接口就是仅仅声明了一个抽象方法的接口。
  • 只有在接受函数式接口的地方才可以使用Lambda表达式。
  • Lambda表达式允许你直接内联,为函数式接口的抽象方法提供实现,并且将整个表达式作为函数式接口的一个实例。
  • Java 8自带一些常用的函数式接口,放在java.util.function包里,包括Predicate<T>Function<T, R>Supplier<T>Consumer<T>Binaryoperator<T>
  • 为了避免装箱操作,对Predicate<T>Function<T, R>等通用函数式接口的原始类型特化:IntPredicateIntToLongFunction等。
  • 环绕执行模式(即在方法所必需的代码中间,需要执行点儿什么操作,比如资源分配和清理)可以配合Lambda提高灵活性和可重用性。
  • Lambda表达式所需要代表的类型称为目标类型。
  • 方法引用让你重复使用现有的方法实现并直接传递它们。
  • ComparatorPredicateFunction等函数式接口都有几个可以用来结合Lambda表达式的默认方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值