Java 8 lambda、Function.identity() 或 t->t

Java 8 lambdas, Function.identity() or t-gt;t(Java 8 lambda、Function.identity() 或 t-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 ->xFunction.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

基础教程推荐