所以我使用Optionals并遇到了一个奇怪的行为。我想知道这是否真的是一个特色"功能"什么......奇怪......
以下是给出的示例: 我有一个带有Optional的方法,其中orElse我想评估另一个可选项。如果其他Optional不存在,我将引发IllegalArgumentException:
firstOptionalVar.orElse(secondOptionalVar.orElseThrow(IllegalArgumentException::new));
现在,如果secondOptionalVar
是一个空的Optional,它将引发IllegalArgumentException,即使firstOptionalVar
存在。这对我来说似乎不对。如果firstOptionalVar
不存在,我希望它只会引发IllegalArgumentException。
使用java7方法来解决这种行为并不是什么大事:
firstOptionalVar.isPresent() ? firstOptionalVar.get() : secondOptionalVar.orElseThrow(IllegalArgumentException::new);
之前有其他人经历过这种行为吗?这真的是选项应该表现的方式吗?
答案 0 :(得分:8)
这是预期的行为。 orElse
期望类型为T
的参数(无论Optional
的通用类型是什么。orElseThrow
都会返回T
,因此需要先对其进行评估,为了将参数传递给orElse
。
你想要的是orElseGet
,它需要Supplier<T>
。这将延迟执行orElseThrow
,直到firstOptionalVar
已经检查过。
所以你的代码应该是这样的:
firstOptionalVar.orElseGet(() -> secondOptionalVar.orElseThrow(IllegalArgumentException::new));
这会将orElseThrow
部分转换为lambda,并且仅在需要时评估它(即,当firstOptionalVar
没有值得到时)。< / p>
答案 1 :(得分:3)
作为一切的核心,您仍然只调用Java方法,因此标准的Java评估顺序适用。
具体来说:secondOptionalVar.orElseThrow(IllegalArgumentException::new)
必须先评估 之前调用firstOptionalVar.orElse()
,因为它提供了firstOptionalVar.orElse()
的参数。
我看不出用Optional
的标准方法解决这个问题的简单方法,你总是可以从两个选项中构建一个流并获得第一个元素或者抛出异常,但它似乎是有点令人费解。