通常,我们编写代码来计算出一堆可用的答案。 让我们看看Java中的情况。
public Widget getAppropriateWidget(CustomerRequest request) {
if (shelfstock.contains(request.getBarcode()) {
return new ShelfWidget();
}
if (backroomStock.contains(request.getBarcode()) {
return new BackroomWidget();
}
if (supplier.contains(request.getEan()) {
return new SupplierWidget();
}
return null ; }
您将不得不想象更复杂的场景,隐藏在上面的简化代码后面。 该算法的作用是按优先级顺序尝试选项,直到找到有效的选项,否则将失败,在这种情况下它将不返回任何内容。
我们还要想象一下,由于某些原因,对contains的调用很昂贵–也许每个对象都隐藏了一个Web服务或复杂的数据库查询。
让我们以两种方式重构上面的代码开始。 让我们使用Optional ,并为每个方法使用子例程。
public Optional<Widget> getAppropriateWidget(CustomerRequest request) {
Optional<Widget> shelfWidget =
getShelfWidget(request);
if (shelfWidget.isPresent()) {
return shelfWidget;
}
Optional<Widget> backroomWidget =
getBackroomWidget(request);
if (backroomWidget.isPresent()) {
return backroomWidget;
}
Optional<Widget> supplierWidget =
getSupplierWidget(request);
if (supplierWidget.isPresent()) {
return supplierWidget;
}
return Optional.empty; } // imagine the subsidiary functions
因此,这比未找到的返回null要好于null ,并且正努力使用子例程来使该函数描述自身,但是存在这样一个问题,即返回的每个Optional对象都无法链接到责任链。
我们可以作弊:
Optional<Widget> shelfWidget = getShelfWidget(request); Optional<Widget> backroomWidget = getBackroomWidget(request); Optional<Widget> supplierWidget = getSupplierWidget(request); return firstNonEmpty(shelfWidget, backroomWidget, supplierWidget); private static Optional<Widget> firstNonEmpty(
Optional<Widget> ... options) {
return Arrays.stream(options)
.filter(Optional::isPresent)
.findFirst() // makes an optional of optional here...
.orElse(Optional.empty()); }
上面的代码更好一些,但是现在必须在选择一个之前预先计算所有可能的答案。 如果答案很快就会出现,我们就需要避免成本高昂的期权计算。
带有可选解决方案的第一个过去的帖子
将流或varargs数组传递给一个函数,该函数由将提供可选参数的对象组成。 如果它们中的任何一个提供非空值,则获胜。
// calling code public Optional<Widget> getAppropriateWidget(CustomerRequest request) {
return firstAvailable(() -> getShelfWidget(request),
() -> getBackroomWidget(request),
() -> getSupplierWidget(request)); } // this is a general purpose solution // feel free to use it @SafeVarargs private static <T> Optional<T> firstAvailable(
Supplier<Optional<T>> ... options) {
return Arrays.stream(options)
.map(Supplier::get)
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty()); }
翻译自: https://www.javacodegeeks.com/2019/11/first-past-the-post.html
本文探讨了在Java中如何使用Optional类型来优化算法,通过重构代码,避免了返回null的潜在问题,同时介绍了如何使用Optional来链接责任链,以及如何在多个可能的答案中选择第一个有效选项。

2388

被折叠的 条评论
为什么被折叠?



