Java8中自带的Optional类详解

使用Java8的新特性 Optional 代替 if - else 解决空指针问题

静态构造方法

JDK提供三个静态方法来构造一个`Optional`


    
    
  1. public final class Optional<T> {
  2. private static final Optional<?> EMPTY = new Optional<>();
  3. private final T value;
  4. // 该方法用来构造一个空的 Optional,如果 Optional 中的 value 为 null 则该 Optional 为不包含值的状态
  5. public static<T> Optional<T> empty () {
  6. @SuppressWarnings("unchecked")
  7. Optional<T> t = (Optional<T>) EMPTY;
  8. return t;
  9. }
  10. // 通过一个非 null 的 value 来构造一个 Optional,
  11. // 返回的 Optional 包含了 value 这个值。对于该方法,传入的参数一定不能为 null,否则便会抛出 NullPointerException
  12. public static <T> Optional<T> of (T value) {
  13. return new Optional<>(value);
  14. }
  15. // 该方法和 of 方法的区别在于,传入的参数可以为 null,如果为 null 的话,返回的就是 Optional.empty()
  16. public static <T> Optional<T> ofNullable (T value) {
  17. return value == null ? empty() : of(value);
  18. }
  19. }

常用方法

isPresent() / ifPresent()


    
    
  1. // 如果值存在返回true,否则返回false
  2. public boolean isPresent () {
  3. return value != null;
  4. }
  5. // 如果Optional实例有值则为其调用consumer ,否则不做处理。
  6. public void ifPresent (Consumer<? super T> consumer) {
  7. if (value != null)
  8. consumer.accept(value);
  9. }

测试


    
    
  1. public class OptionalTest {
  2. public static void main (String[] args) {
  3. User user = new User();
  4. Optional<User> optional = Optional.ofNullable(user);
  5. optional.ifPresent(s -> System.out.println(s));
  6. }
  7. }

Get()

获取Optional中的值,这个值也就是我们的值,Optional相当于就是一个外壳。


    
    
  1. public T get () {
  2. if (value == null) {
  3. throw new NoSuchElementException( "No value present");
  4. }
  5. return value;
  6. }

orElse() / orElseGet() / orElseThrow()


    
    
  1. // 如果Optional中的值不为空,则返回Optional中的值,如果为空,则返回other值,
  2. public T orElse (T other) {
  3. return value != null ? value : other;
  4. }
  5. // 如果Optional中存在值,则返回值,否则返回other调用的结果
  6. public T orElseGet (Supplier<? extends T> other) {
  7. return value != null ? value : other.get();
  8. }
  9. // 如果Optional中的值存在,则返回值,值不存在,则抛出异常函数Supplier中的异常
  10. public <X extends Throwable> T orElseThrow (Supplier<? extends X> exceptionSupplier) throws X {
  11. if (value != null) {
  12. return value;
  13. } else {
  14. throw exceptionSupplier.get();
  15. }
  16. }

测试


    
    
  1. String value = "2";
  2. String orElse = Optional.ofNullable(value).orElse( "1");
  3. System.out.println(orElse); //2
  4. String value = null;
  5. String orElse = Optional.ofNullable(value).orElse( "1");
  6. System.out.println(orElse); //1
  7. -------------------------------------------------------
  8. public class OptionalTest {
  9. public static void main (String[] args) {
  10. String value = null;
  11. String orElse = Optional.ofNullable(value).orElseGet(OptionalTest::get);
  12. System.out.println(orElse); // 123
  13. String value = "2";
  14. String orElse = Optional.ofNullable(value).orElseGet(OptionalTest::get);
  15. System.out.println(orElse); // 2
  16. }
  17. public static String get (){
  18. return "123";
  19. }
  20. }
  21. -------------------------------------------------------
  22. public class OptionalTest {
  23. public static void main (String[] args) {
  24. String value = null;
  25. String orElse = Optional.ofNullable(value).orElseThrow(() -> new RuntimeException( "不存在值"));
  26. System.out.println(orElse);
  27. }
  28. }

map() / flatMap()

  • map(Function):如果 Optional 不为空,应用 Function 于 Optional 中的内容,并返回结果。否则直接返回 Optional.empty

  • flatMap(Function):同 map(),但是提供的映射函数将结果包装在 Optional 对象中,因此 flatMap() 不会在最后进行任何包装。

以上方法都不适用于数值型 Optional。一般来说,流的 filter() 会在 Predicate 返回 false 时移除流元素。而 Optional.filter() 在失败时不会删除 Optional,而是将其保留下来,并转化为空。


    
    
  1. // 将Optional中的值作为参数传递到map中,如果传入的值为空,则返回一空的Optional对象,相当于Optional.empty(),
  2. // 如果不为空,我们可以返回一个可以描述描述结果的返回值(Optional中的值,这个值可以重新赋值)
  3. public<U> Optional<U> map (Function<? super T, ? extends U> mapper) {
  4. Objects.requireNonNull(mapper);
  5. if (!isPresent())
  6. return empty();
  7. else {
  8. return Optional.ofNullable(mapper.apply(value));
  9. }
  10. }
  11. // 如果Optional中值存在,那么返回一个基于Optional的值(如Optional),
  12. // 如果Optional中的值不存在,则返回一空的Optional对象,相当于Optional.empty(),
  13. // 与map不同, map返回的是一个值,而flatMap返回一个基于Optional的值
  14. public<U> Optional<U> flatMap (Function<? super T, Optional<U>> mapper) {
  15. Objects.requireNonNull(mapper);
  16. if (!isPresent())
  17. return empty();
  18. else {
  19. return Objects.requireNonNull(mapper.apply(value));
  20. }
  21. }

测试


    
    
  1. public class OptionalTest {
  2. public static void main (String[] args) {
  3. User user = null;
  4. Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
  5. System.out.println(optional); //Optional.empty
  6. User user = new User();
  7. user.setUsername( "Admin");
  8. Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
  9. System.out.println(optional); // Optional[Admin]
  10. }
  11. public static String getMap (User user){
  12. return user.getUsername();
  13. }
  14. -------------------------------------------------------
  15. User user = new User();
  16. user.setUsername( "Admin");
  17. Optional<String> optional = Optional.ofNullable(user).flatMap(OptionalTest::getFlatMap);
  18. System.out.println(optional);
  19. } ​
  20. public static Optional<String> getFlatMap (User user){
  21. return Optional.ofNullable(user).map(User::getUsername);
  22. }

filter()

将Optional中的值作为参数传入,如果符合规则,那么返回一个Optional对象,否则返回一个空的Optional 对象(Optional.empty)


    
    
  1. public Optional<T> filter (Predicate<? super T> predicate) {
  2. Objects.requireNonNull(predicate);
  3. if (!isPresent())
  4. return this;
  5. else
  6. return predicate.test(value) ? this : empty();
  7. }

实战

ifPresent(),这是一个终端操作,如果value存在则会调用指定的消费方法


    
    
  1. // 获取 book 的值,若 book 为 null 则返回默认值
  2. String book = Optional.ofNullable(person).map(Person::getBook).orElse( "default");
  3. // person 不为 null 则打印薪水
  4. Optional.ofNullable(person).ifPresent(p -> System.out.println(p.getSalary()));
  5. // 若 book 为 null,则设置默认值
  6. Optional.ofNullable(person)
  7. .map(Person::getComputer)
  8. .ifPresent(c -> c.setBrandName( "default name"));
  9. Optional.ofNullable(person)
  10. .map(Person::getComputer)
  11. .ifPresent( this::consumerTest);
  12. public void consumerTest (Computer computer){
  13. System.out.println( "consumer test");
  14. System.out.println(computer);
  15. }
  16. // 获取brand,若 brandName 为 "",则抛出异常
  17. // 因为 map只能过滤掉 null 值,而在工作中通常还需要做其它的判断,所以我们可以使用 map 去解析实体类中的某个属性,然后使用 filter 进行对应的过滤
  18. String brand = Optional.ofNullable(person)
  19. .map(Person::getComputer)
  20. .map(Computer::getBrandName)
  21. .filter(b -> !b.equals( ""))
  22. .orElseThrow(() -> new NumberFormatException( "品牌为空"));
  23. System.out.println( "brand: " + brand);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值