Java 8 lambdas、Function.identity() 或 t->t [英] Java 8 lambdas, Function.identity() or t->t

查看:33
本文介绍了Java 8 lambdas、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 lambdas、Function.identity() 或 t->t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆