我对该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(反之亦然).我认为第二种选择更具可读性(当然是品味问题).但是,有没有"真正的"理由为什么应该首选?
当我使用Java 8的新语法糖迭代一个集合时,例如
myStream.forEach(item -> {
// do something useful
});
Run Code Online (Sandbox Code Playgroud)
这不等同于下面的"旧语法"片段吗?
myStream.forEach(new Consumer<Item>() {
@Override
public void accept(Item item) {
// do something useful
}
});
Run Code Online (Sandbox Code Playgroud)
这是否意味着Consumer每次迭代集合时都会在堆上创建一个新的匿名对象?这需要多少堆空间?它有什么性能影响?这是否意味着我在迭代大型多级数据结构时应该使用旧样式for循环?
考虑我有以下代码:
class Foo {
Y func(X x) {...}
void doSomethingWithAFunc(Function<X,Y> f){...}
void hotFunction(){
doSomethingWithAFunc(this::func);
}
}
Run Code Online (Sandbox Code Playgroud)
假设hotFunction经常被调用.那么缓存是否可取this::func,也许是这样的:
class Foo {
Function<X,Y> f = this::func;
...
void hotFunction(){
doSomethingWithAFunc(f);
}
}
Run Code Online (Sandbox Code Playgroud)
就我对java方法引用的理解而言,虚拟机在使用方法引用时会创建匿名类的对象.因此,缓存引用将仅创建该对象一次,而第一种方法在每个函数调用上创建它.它是否正确?
是否应缓存出现在代码中热位置的方法引用,或者VM是否能够对此进行优化并使缓存变得多余?是否存在关于此的一般最佳实践,或者这种高度VM实现是否特定于此类缓存是否有用?