Java 8 lambdas, Function.identity() or t-gt;t(Java 8 lambda、Function.identity() 或 t-t)
问题描述
我对 Function.identity()
方法的使用有疑问.
I have a question regarding the usage of the Function.identity()
method.
想象一下下面的代码:
Arrays.asList("a", "b", "c")
.stream()
.map(Function.identity()) // <- This,
.map(str -> str) // <- is the same as this.
.collect(Collectors.toMap(
Function.identity(), // <-- And this,
str -> str)); // <-- is the same as this.
你有什么理由应该使用 Function.identity()
而不是 str->str
(反之亦然).我认为第二个选项更具可读性(当然是口味问题).但是,是否有任何真正"的理由应该首选一个?
Is there any reason why you should use Function.identity()
instead of str->str
(or vice versa). I think that the second option is more readable (a matter of taste of course). But, is there any "real" reason why one should be preferred?
推荐答案
在当前的 JRE 实现中,Function.identity()
将始终返回相同的实例,而每次出现 identifier->identifier
不仅会创建自己的实例,甚至还会有一个不同的实现类.有关详细信息,请参阅此处.
As of the current JRE implementation, Function.identity()
will always return the same instance while each occurrence of identifier -> identifier
will not only create its own instance but even have a distinct implementation class. For more details, see here.
原因是编译器生成了一个合成方法来保存该 lambda 表达式的平凡主体(在 x->x
的情况下,相当于 return identifier;
) 并告诉运行时创建调用此方法的功能接口的实现.所以运行时只看到不同的目标方法,当前的实现不会分析方法来找出某些方法是否等效.
The reason is that the compiler generates a synthetic method holding the trivial body of that lambda expression (in the case of x->x
, equivalent to return identifier;
) and tell the runtime to create an implementation of the functional interface calling this method. So the runtime sees only different target methods and the current implementation does not analyze the methods to find out whether certain methods are equivalent.
所以使用 Function.identity()
而不是 x ->x
可能会节省一些内存,但如果您真的认为 x ->x
比 Function.identity()
更具可读性.
So using Function.identity()
instead of x -> x
might save some memory but that shouldn’t drive your decision if you really think that x -> x
is more readable than Function.identity()
.
您还可以考虑,在启用调试信息的情况下进行编译时,合成方法将有一个 line debug 属性指向包含 lambda 表达式的源代码行,因此您有机会找到特定的源代码Function
实例同时调试.相比之下,在调试操作时遇到 Function.identity()
返回的实例,您将不知道是谁调用了该方法并将该实例传递给操作.
You may also consider that when compiling with debug information enabled, the synthetic method will have a line debug attribute pointing to the source code line(s) holding the lambda expression, therefore you have a chance of finding the source of a particular Function
instance while debugging. In contrast, when encountering the instance returned by Function.identity()
during debugging an operation, you won’t know who has called that method and passed the instance to the operation.
这篇关于Java 8 lambda、Function.identity() 或 t->t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java 8 lambda、Function.identity() 或 t->t
基础教程推荐
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- 降序排序:Java Map 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01