在列表中执行可运行对象

时间:2018-07-24 08:25:20

标签: java java-8

我有一个要使用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)

1 个答案:

答案 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将负责创建Consumer实例,并具有重用现有实例的自由度,这在当前实现中会发生,而 non使用lambda表达式或方法引用捕获功能接口的实例,该实例适用于两个变体,因此将只有一个Consumer实例,即使在随后对该语句的求值中也可以重复使用。 >

与当前编译器的唯一区别是,lambda表达式r->r.run()将在您的类中生成一个调用run()方法的方法,而对于方法引用,运行时生成的Consumer实现类将直接调用它,这使得方法引用在难以测量范围内更加有效。