我对该Function.identity()
方法的用法有疑问.
想象一下以下代码:
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.
Run Code Online (Sandbox Code Playgroud)
是否有任何理由你应该使用Function.identity()
而不是str->str
(反之亦然).我认为第二种选择更具可读性(当然是品味问题).但是,有没有"真正的"理由为什么应该首选?
Hol*_*ger 279
从当前的JRE实现开始,Function.identity()
将始终返回相同的实例,而每次出现时identifier -> identifier
不仅会创建自己的实例,甚至还会有一个不同的实现类.有关详细信息,请参阅此处.
原因是编译器生成一个合成方法,该方法保存该lambda表达式的普通主体(在x->x
等效的情况下return identifier;
)并告诉运行时创建调用此方法的功能接口的实现.因此,运行时只能看到不同的目标方法,并且当前实现不会分析方法以确定某些方法是否相同.
因此,使用Function.identity()
而不是x -> x
可能会节省一些内存,但如果您真的认为它x -> x
比可读性更强,则不应该推动您的决定Function.identity()
.
您还可以考虑在启用调试信息进行编译时,合成方法将具有指向包含lambda表达式的源代码行的行调试属性,因此您可以Function
在调试时查找特定实例的源代码..相反,当遇到Function.identity()
调试操作期间返回的实例时,您将不知道谁调用了该方法并将实例传递给操作.
Psh*_*emo 80
在你的例子中,两者之间没有太大的区别str -> str
,Function.identity()
因为内部简单t->t
.
但有时我们不能使用,Function.identity
因为我们不能使用Function
.看看这里:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
Run Code Online (Sandbox Code Playgroud)
这将编译好
int[] arrayOK = list.stream().mapToInt(i -> i).toArray();
Run Code Online (Sandbox Code Playgroud)
但如果你试图编译
int[] arrayProblem = list.stream().mapToInt(Function.identity()).toArray();
Run Code Online (Sandbox Code Playgroud)
因为mapToInt
期望ToIntFunction
,你将得到编译错误,这与之无关Function
.也ToIntFunction
没有identity()
方法.
Jas*_*onN 41
来自JDK来源:
static <T> Function<T, T> identity() {
return t -> t;
}
Run Code Online (Sandbox Code Playgroud)
所以,不,只要它在语法上是正确的.
归档时间: |
|
查看次数: |
100035 次 |
最近记录: |