mirror of
https://github.com/sjsdfg/effective-java-3rd-chinese.git
synced 2025-01-26 20:30:36 +08:00
update 43. 方法引用优于 lambda 表达式
This commit is contained in:
parent
0f864f4fde
commit
3a1d61898e
@ -17,7 +17,7 @@ map.merge(key, 1, Integer::sum);
|
||||
|
||||
方法的参数越多,你可以通过方法引用消除更多的样板。 然而,在一些 lambda 中,选择的参数名称提供了有用的文档,使得 lambda 比方法引用更具可读性和可维护性,即使 lambda 看起来更长。
|
||||
|
||||
只要方法引用能做的事情,就没有 lambda 不能完成的(只有一种情况例外 - 如果你好奇的话,参见 JLS,9.9-2)。 也就是说,使用方法引用通常会得到更短,更清晰的代码。 如果 lambda 变得太长或太复杂,它们也会给你一个结果:你可以从 lambda 中提取代码到一个新的方法中,并用对该方法的引用代替 lambda。 你可以给这个方法一个好名字,并把它文档记录下来。
|
||||
只要方法引用能做的事情,就没有 lambda 不能完成的(只有一种情况例外 - 如果你好奇的话,参见 [JLS,9.9-2](https://docs.oracle.com/javase/specs/jls/se12/html/jls-9.html#jls-9.9))。 也就是说,使用方法引用通常会得到更短,更清晰的代码。 如果 lambda 变得太长或太复杂,它们也会给你一个结果:你可以从 lambda 中提取代码到一个新的方法中,并用对该方法的引用代替 lambda。 你可以给这个方法一个好名字,并把它文档记录下来。
|
||||
|
||||
如果你使用 IDE 编程,它将提供替换 lambda 的方法,并在任何地方使用方法引用。通常情况下,你应该接受这个提议。偶尔,lambda 会比方法引用更简洁。这种情况经常发生在方法与 lambda 相同的类中。例如,考虑这段代码,它被假定出现在一个名为 `GoshThisClassNameIsHumongous` 的类中:
|
||||
|
||||
@ -33,9 +33,9 @@ service.execute(() -> action());
|
||||
|
||||
使用方法引用的代码段并不比使用 lambda 的代码片段更短也不清晰,所以优先选择后者。 在类似的代码行中,`Function` 接口提供了一个通用的静态工厂方法来返回标识函数 `Function.identity()`。 不使用这种方法,而是使用等效的 lambda 内联代码:`x -> x`,通常更短,更简洁。
|
||||
|
||||
许多方法引用是指静态方法,但有四种方法没有。 等同的 Lambda 其中两个是特定(bound)和任意(unbound)对象方法引用。 在特定对象引用中,接收对象在方法引用中指定。 特定对象引用在本质上与静态引用类似:函数对象与引用的方法具有相同的参数。 在任意对象引用中,接收对象在应用函数对象时通过方法的声明参数之前的附加参数指定。 任意对象引用通常用作流管道(pipelines)中的映射和过滤方法(条目 45)。 最后,对于类和数组,有两种构造方法引用。 构造方法引用用作工厂对象。 下表总结了所有五种方法引用:
|
||||
许多方法引用是指静态方法,但有 4 种方法没有引用静态方法。 其中两个 Lambda 等式是特定(bound)和任意(unbound)对象方法引用。 在特定对象引用中,接收对象在方法引用中指定。 特定对象引用在本质上与静态引用类似:函数对象与引用的方法具有相同的参数。 在任意对象引用中,接收对象在应用函数对象时通过方法的声明参数之前的附加参数指定。 任意对象引用通常用作流管道(pipelines)中的映射和过滤方法(条目 45)。 最后,对于类和数组,有两种构造方法引用。 构造方法引用用作工厂对象。 下表总结了所有五种方法引用:
|
||||
|
||||
|方法引用类型<br>Method Ref Type|举例<br>Example|等同的 Lambda<br>Lambda Equivalent|
|
||||
|方法引用类型<br>Method Ref Type|举例<br>Example|Lambda 等式<br>Lambda Equivalent|
|
||||
|:--:|:--:|:--: |
|
||||
|Static|Integer::parseInt|str -> Integer.parseInt(str)|
|
||||
|Bound|Instant.now()::isAfter|Instant then = Instant.now(); <br> t -> then.isAfter(t)|
|
||||
|
Loading…
Reference in New Issue
Block a user