转换可运行于供应商

问题描述 投票:3回答:2

如何才能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);
}

在这里,我想重用方法useSupplieruseRunnable,例如,因为我不想重复的代码。 useSupplier的行为没有关系这个问题,让我们说,它包装抛出的异常,或使用供应商在同步块。


编辑:为了澄清,useSupplier不与提供的值进行交互的方法,它只是返回。 useSupplier的功能是检索在某些情况下,从供应商的价值,在我的情况下,它捕获(特定)RuntimeExceptions,用它创建一个新的异常为原因把它扔了:

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

java java-8 functional-interface
2个回答
7
投票

在你的情况不能避免创建新的对象。即使是转换一个Runnable到供应商的方法的地方,就会有创建一个对象。所以,你的解决方案是有效的,你不会找到任何好转。

该供应商预计将提供价值和可运行只是代表一个动作注意。它们被用于不同的目的。所以,你将可运行于供应商的需求可能涉及一个设计问题的结果。


1
投票

看你的设计,你可能只是没有返回值寻找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其忽略。

© www.soinside.com 2019 - 2024. All rights reserved.