从自身内部更改可选<runnable>

时间:2015-11-17 09:16:53

标签: lambda java-8 optional

我有一个变量oneTimeTask。它的类型是:

Optional<Runnable> oneTimeTask=...;

您是否认为此示例是“重置”Optional<Runnable>

的一种肮脏方式
oneTimeTask = Optional.of(() ->  {
            /*Run task
            ...*/
            oneTimeTask= Optional.empty();
        });

......你怎么看?

oneTimeTask在应用程序运行时会多次获得Optional(someRunnable)值,但大多数情况下该值为空。

我应该使用Supplier<Runnable>还是Supplier<Optional<Runnable>>? 如果是的话,你会如何实现它? (我对供应商类不太熟悉)

我愿意接受任何替代(更好)的方式来获得相同的结果。

2 个答案:

答案 0 :(得分:4)

由于您想要控制从一次通话返回的内容,您需要供应商。

AtomicBoolean once = new AtomicBoolean();
Supplier<Runnable> oneTimeTask = () -> once.getAndSet(true) 
                                     ? () -> {} 
                                     : () -> { /* do one */ };

或更简单地说,你可以拥有一个Runnable

Runnable runs = () -> {
    if (once.getAndSet(true)) return;
    /* do once */
};

答案 1 :(得分:1)

看起来您将oneTimeTask定义为实例或静态字段(否则必须声明final才能从lambda中访问)。 This is not the purpose of Optional.

相反,您可以通过将字段保持为简单Runnable来简化代码,其初始值为无操作:

private Runnable oneTimeTask = () -> {};

在你的lambda中,完成后将其重置为no-op:

oneTimeTask = () ->  {
        /*Run task
        ...*/
        oneTimeTask= () -> {};
    };

现在,当您想要使用它时,您不必检查它是null,也不必处理Optional api。