如何才能Runnable
转换为Supplier
?
public <T> T useSupplier(Supplier<T> supplier) {
// Does something with supplier and returns supplied value
...
return value;
}
public void useRunnable(Runnable runnable) {
// Somehow convert runnable to Supplier
...
useSupplier(supplier);
}
在这里,我想重用方法useSupplier
为useRunnable
,例如,因为我不想重复的代码。 useSupplier
的行为没有关系这个问题,让我们说,它包装抛出的异常,或使用供应商在同步块。
编辑:为了澄清,useSupplier
不与提供的值进行交互的方法,它只是返回。 useSupplier
的功能是检索在某些情况下,从供应商的价值,在我的情况下,它捕获(特定)RuntimeException
s,用它创建一个新的异常为原因把它扔了:
public <T> T useSupplier(Supplier<T> supplier) {
try {
return supplier.get();
}
catch (RuntimeException runtimeException) {
throw new MyException("Supplier threw exception", runtimeException);
}
}
下面的解决方案没有(在Java中8)工作:
useSupplier(runnable);
useSupplier(runnable::run);
useSupplier((Supplier<Void>) runnable::run);
一个解决方案,我可以想出是创建一个新Supplier
返回一个任意值:
useSupplier(() -> {
runnable.run();
return null;
});
是否有一个更小的解决方案?
编辑:正如在评论中指出的霍尔格,使用runnable::run
也将创造新的λ情况下,因为它是有状态的,也见this answer。
在你的情况不能避免创建新的对象。即使是转换一个Runnable到供应商的方法的地方,就会有创建一个对象。所以,你的解决方案是有效的,你不会找到任何好转。
该供应商预计将提供价值和可运行只是代表一个动作注意。它们被用于不同的目的。所以,你将可运行于供应商的需求可能涉及一个设计问题的结果。
看你的设计,你可能只是没有返回值寻找Consumer
它接受一个类型的和公正的处理(消耗),并可以用来适应可运行为好,而不是其在另一方面,预计到Supplier
返回(供给)的值的后处理。
你可以使用这样的:
private static <T> void useConsumer(Consumer<T> consumer, T val) {
// Does something with supplier and returns supplied value
consumer.accept(val);
}
public static <T> void useRunnable(Runnable runnable) {
useConsumer(Runnable::run, runnable);
}
如果要求是用于确保Supplier
,那么你就可以调用该方法为:
public static void useRunnable(Runnable runnable) {
useSupplier(() -> runnable); // the useSupplier returns the 'runnable' when this method is called
}
正如在评论中提到的,现在当你调用useRunnable
,该useSupplier
将返回相同的runnable
,但该方法useRunnable
再次,因此是完全void
其忽略。