• Optional类详解 艾尔夏尔


    简述

      Optional类是java8中引入的一个非常有用的类,主要用处是解决编程中的空指针异常,本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。

    空指针异常的麻烦

      在java8之前,任何访问对象方法或属性的调用都有可能导致空指针异常,例如:

    String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();

      这行代码如果我们需要确保不触发异常,我们就要写成:

    if (user != null) {
        Address address = user.getAddress();
        if (address != null) {
            Country country = address.getCountry();
            if (country != null) {
                String isocode = country.getIsocode();
                if (isocode != null) {
                    isocode = isocode.toUpperCase();
                }
            }
        }
    }

    创建Optional实例

      使用empty()创建空实例

    Optional<User> emptyOpt = Optional.empty();

      尝试访问emptyOpt变量的值会导致NoSuchElementException

      使用of()或ofNullable()方法创建包含值的Optional,不同之处在于:如果你把 null 值作为参数传递进去,of() 方法会抛出 NullPointerException

    Optional<User> opt1 = Optional.of(user);
    Optional<User> opt1 = Optional.ofNullable(user);

    访问Optional对象的值

      使用get()方法获取Optional的值

    Optional<User> opt1 = Optional.of(user);
    User tmp = opt1.get();

      get方法会在值为null的时候抛出异常,我们可以用ifPresent()方法验证值是否为空

    返回默认值

      orElse()方法可以在创建实例时就指定返回的默认值

    User user = null;
    User user2 = new User("anna@gmail.com", "1234");
    User result = Optional.ofNullable(user).orElse(user2);

      因为user是空,所以此时我们想获取result的值的话会得到user2

      我们也可以使用orElseGet(),如果没有值,它会执行作为参数传入的 Supplier(供应者) 函数式接口,并将返回其执行结果

    User result = Optional.ofNullable(user).orElseGet( () -> user2);

      不同的是使用orElse的话无论创建的值是否为空,都会orElse里的代码,如果里面有创建新的实例,这会对性能产生很大影响

      另外我们可以使用orElseThrow(),它会在对象为空的时候抛出异常,而不是返回备选的值

    User result = Optional.ofNullable(user)
            .orElseThrow( () -> new IllegalArgumentException());

      此时如果user为空,会抛出我们定义的异常IllegalArgumentException

    转换值

      我们可以使用map方法,将 Optional里的元素进行转换

    User user = new User("anna@gmail.com", "1234");
    String email = Optional.ofNullable(user)
            .map(u -> u.getEmail()).orElse("default@gmail.com");

      注意无论是user为null,还是user里的Email为空,都会触发返回orElse里的默认值,这也就Optional的map操作的链式调用的精髓,我们可以不断的接着写map,无需一次次地判断是否为空

      注意如果当对象发生Optinoal嵌套的时候,我们需要使用flatMap方法,详细请看:https://blog.csdn.net/qq_35634181/article/details/101109300

    过滤值

      filter()接受一个Predicate参数,返回测试结果为 true 的值

      用法和stream的filter一模一样,例如我们可以检查用户的邮箱是否带@

    User user = new User("anna@gmail.com", "1234");
    Optional<User> result = Optional.ofNullable(user)
            .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));

    对原来if的改进

      对于User类我们对其进行重构,使其getter方法返回Optional类

    public class User {
        private Address address;
    
        public Optional<Address> getAddress() {
            return Optional.ofNullable(address);
        }
    
        // ...
    }
    public class Address {
        private Country country;
    
        public Optional<Country> getCountry() {
            return Optional.ofNullable(country);
        }
    
        // ...
    }
    View Code

      上面的嵌套结构可以用下面的图来表示:

      之前冗杂的if判断我们就可以改成这样:

    String result = Optional.ofNullable(user)
            .flatMap(u -> u.getAddress())
            .flatMap(a -> a.getCountry())
            .map(c -> c.getIsocode())
            .orElse("default");

      也可以简写成这样:

    String result = Optional.ofNullable(user)
      .flatMap(User::getAddress)
      .flatMap(Address::getCountry)
      .map(Country::getIsocode)
      .orElse("default");

    Reference

      https://blog.csdn.net/wwe4023/article/details/80760416

      https://blog.csdn.net/qq_35634181/article/details/101109300

  • 相关阅读:
    python学习(3)
    Python学习(2)
    powerDesigner的初步使用
    单阶经典检测器: YOLO V1 (一)
    单阶多层检测器: SSD(三)改进算法
    单阶多层检测器: SSD(二)算法综述
    单阶多层检测器: SSD(一)
    两阶经典检测器:Faster RCNN(三)改进算法
    【转载】http协议介绍
    【转载】dts介绍
  • 原文地址:https://www.cnblogs.com/CNLayton/p/15830900.html
Copyright © 2020-2023  润新知