我有一个要使用lambda表达式调用的可运行对象列表:
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(r->r.run());
除了以下方法以外,是否存在“更好”(更有效)的快捷方式来调用Runnable
的{{1}}方法?
run()
我认为此表达式将转换为将列表中的可运行实例包装的Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(Runnable::run);
。
编辑:
我的假设/担心(可能是错误的)是编译器会将表达式Runnable
转换为类似这样的内容,因此效率不高:
list.forEach(Runnable::run)
答案 0 :(得分:1)
你是否写
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(r->r.run());
或
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(Runnable::run);
无论哪种情况,都会生成一个 Consumer
的实例,这正是Iterable.forEach
所期望的。
消费者将等同于
Arrays.asList(runnable1, runnable2, runnable3, ...).forEach(new Consumer<Runnable>() {
public void accept(Runnable r) {
r.run();
}
});
但这不是可运行对象的包装,因为它封装了应用于作为参数传入的任意Runnable
实例的操作。因此,整个Consumer
操作最多创建一个forEach
实例。
如this answer中所述,JVM将负责创建 与当前编译器的唯一区别是,lambda表达式Consumer
实例,并具有重用现有实例的自由度,这在当前实现中会发生,而 non使用lambda表达式或方法引用捕获功能接口的实例,该实例适用于两个变体,因此将只有一个Consumer
实例,即使在随后对该语句的求值中也可以重复使用。> >
r->r.run()
将在您的类中生成一个调用run()
方法的方法,而对于方法引用,运行时生成的Consumer
实现类将直接调用它,这使得方法引用在难以测量范围内更加有效。