Java8 Optional高级玩法


Optional的出现给Java带来了很多可玩的玩具。今天,我们专注于如何正确使用orElse,orElseGet等其他方式使Optionals更好的为您工作。毕竟可以避免null带来的系统危害。

Optional其实就是Java的一个monad的实现。不要被monad这个词吓到 它只是一个封装来处理一个类型的具体情况 – 在这种情况下,一个空值的可能性。只要认为它是一个包装,强制用户检查值是否存在。

当以声明方式使用Optional时,我们可以在其上执行映射函数。只有在Optional中填充了一个值,才会执行与map function一起提供的lambda。

图0:Java8 Optional高级玩法

运行该 execute()方法时,控制台输出显然是:

only run if optional is filled

如果我们将maybeString的代码更改为 Optional.empty() 并再次执行,如预期的那样,没有任何反应。

替代if else

但是当我们想要当Optional是null的时候的判断流程,我们可以选择 else(), elseGet(), 和 elseThrow()。最后一个,我们可以抛出一个Exception,但是如果我们想要做一些不同的事情呢?

下面的代码看起来很直观点。

图1:Java8 Optional高级玩法

通过阅读代码,我们可能期望newString会给出值, “foo” 因为 maybeString是一个包含值的可选项。 运行该 execute()
方法时,以下输出将在控制台中结束:

only run if optional is filled

only run if empty

foo

我们仍然可以得出这样的结论: newString的值最终会变成null。另一件我们可以看到的是,字符串“only run if empty”也被打印到控制台。所以即使Optional包含一个值,里面的 orElse()方法仍然在执行中。

当我们改变 execute()方法而orElseGet()不是使用方法 时 orElse(), 我们还需要将方法调用更改runIfEmpty()

的方法为:

图2:Java8 Optional高级玩法

现在我们运行execute()方法,我们看到以下内容:

only run if optional is filled

foo 在使用这个实现时,我们看到里面的方法 orElseGet()没有被执行。这是我们所希望看到的。

总结

当我们只是使用映射为变量赋值时,您在使用orElse()来代替原来的判断流程中不会有任何问题 。你只需要确保里面的代码 orElse()是完全没有副作用的。

另一方面,如果你需要基于一个可选的引导行为,例如当用户没有找到时创建一个新的用户,你应该使用这个 orElseGet()构造。不管可选的值如何,你可能都不希望你的替代流程被执行。

在函数式编程的过程中,当你实际执行代码时,你只能看到结果。所以当然,我现在可以主张编写正确的测试代码(而且你应该),但是最好事先知道它的区别。这个差别是微妙的,但是如果你不小心的话,会产生很大的影响。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java 8引入了Optional类,它是一个容器对象,可以包含或者不包含非空值。Optional类主要用于解决空指针异常的问题,它提供了一种优雅的方式来处理可能为空的值。 下面是Java 8 Optional的使用方式: 1. 创建Optional对象: - 使用静态方`Optional.of(value)`创建一个包含非空值的Optional对象。 - 使用静态方`Optional.empty()`创建一个空的Optional对象。 - 使用静态方`Optional.ofNullable(value)`创建一个包含可能为空值的Optional对象。 2. 判断Optional对象是否包含值: - 使用`isPresent()`方判断Optional对象是否包含非空值。 - 使用`isEmpty()`方判断Optional对象是否为空。 3. 获取Optional对象的值: - 使用`get()`方获取Optional对象中的值。注意:如果Optional对象为空,调用`get()`方会抛出NoSuchElementException异常。 4. 处理Optional对象的值: - 使用`ifPresent(Consumer<? super T> consumer)`方,传入一个Consumer函数式接口来处理Optional对象中的值。如果Optional对象非空,则执行传入的Consumer接口中的逻辑。 - 使用`orElse(T other)`方,如果Optional对象为空,则返回传入的默认值other。 - 使用`orElseGet(Supplier<? extends T> other)`方,如果Optional对象为空,则通过传入的Supplier函数式接口生成一个默认值。 - 使用`orElseThrow(Supplier<? extends X> exceptionSupplier)`方,如果Optional对象为空,则通过传入的Supplier函数式接口抛出一个异常。 5. 使用Optional进行链式调用: - 使用`map(Function<? super T, ? extends U> mapper)`方,传入一个Function函数式接口来对Optional对象中的值进行转换。 - 使用`flatMap(Function<? super T, Optional<U>> mapper)`方,传入一个Function函数式接口来对Optional对象中的值进行转换,并返回一个新的Optional对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值