java8 Optional

1. Optional 出现的意义

Optional 是从 JDK1.8 开始提供的一个容器类, 主要用于避免空指针异常(NPE), 其提供的一系列方法配合 Lambda 表达式可以让代码更加清晰, 语义化, 以及避免了空指针异常的问题这里要注意是避免空指针异常, 而不是避免返回null.

2.Optional的常用api

  • Optional.of() :创建一个Optional实例,但是传入null会报空指针异常
  • Optional.empty() :创建一个空的Optional实例
  • Optional.ofNullable(T t) :如果t不为空,则创建Optional实例,如果为null则创建一个空的Optional实例
  • isPresent() : 判断是否包含值
  • orElse(T t) : 如果调用的对象包含值则返回该值,否则返回t
  • orElseGet(Supplier s) :如果调用的对象包含值则返回该值,否则返回s获取的值。
  • map(Function f) : 如果有值,对其处理。并返回处理后的Optional,否则返回Optional.empty();
  • flatMap(Function f) : 与map相似,要求f返回的值必须是Optional.

3.代码验证

  1. Optional.of()
   /**
   * 创建一个Optional实例,但是传入null会报空指针异常
   */
    public static void testOf(){
      Optional<Employee> employee = Optional.of(new Employee());
      System.out.println( employee.get());
      System.out.println("-------------------");

      // 传入nul直接报空指针异常
      Optional<Employee> employee1 = Optional.of(null);
  }
  1. Optional.empty()
    /**
     * 创建一个空的Optional实例
     */
    public static void testEmpty(){
        Optional<Employee> empty = Optional.empty();
        //返回一个空的Optional,如果调用他的get方法会报空指针。
        System.out.println(empty.get());
    }
  1. Optional.ofNullable(T t)
    此方法是of()和empty()的结合,建议使用此方法生成Optional对象
    /**
     * 如果t不为空,则创建Optional实例,如果为null则创建一个空的Optional实例
     */
    public static void ofNullable(){
        // 如果参数传null,则底层调用empty方法,否则底层调用of方法。
        Optional<Employee> employee = Optional.ofNullable(new Employee());  // 调用of方法
        System.out.println(employee.get());

        System.out.println("-----------------");

        Optional<Employee> employee1 = Optional.ofNullable(null);  // 调用empty方法
        // 由于是空的Optional所有这一句报空指针异常。
        System.out.println(employee1.get());
    }

  1. isPresent()
    /**
     *  判断是否包含值
     */
    public static void testIsPresent(){
        Optional<Employee> employee = Optional.ofNullable(null);
        if (employee.isPresent()){
            // 此时得到一个空的Optional,经过isPresent判断后为false所有不会执行这一句。
            System.out.println(employee.get());
        }
    }
  1. orElse(T t)
    /**
     * 如果调用的对象包含值则返回该值,否则返回t
     */
    public static void testOrElse(){
        Optional<Employee> employee = Optional.ofNullable(null);
        Employee employee1 = employee.orElse(new Employee());
        System.out.println(employee1);
    }
  1. orElseGet(Supplier s)
    此方法和orElse相似,不过这个方法可以的参数可以传入一个表达式,在表达式中可以做任何事情,相比orElse方法更为灵活
    /**
     * 如果调用的对象包含值则返回该值,否则返回s获取的值。
     *
     */
    public static void testOrElseGet(){
        Optional<Employee> employee = Optional.ofNullable(null);
        Employee employee1 = employee.orElseGet( () -> {
            System.out.println("---");
            return new Employee();});
        System.out.println(employee1);
    }

  1. map(Function f)
    这个方法传入一个函数型接口Function的实现,返回一个Option
    /**
     * 如果有值,对其处理。并返回处理后的Optional,否则返回Optional.empty();
     */
    public static void testMap(){
        Optional<Employee> employee = Optional.ofNullable(new Employee("吴国庆",29,999.999));
        Optional<String> s = employee.map(TestOptional::test);
        System.out.println(s.get());
    }

    public static String test(Employee employee){
        return employee.getName();
    }
  1. flatMap(Function f)
    这个方法和map方法比较类似,不同的时这个方法的Function接口的实现需要返回一个Option对象,而map方法则可以返回任意对象,这样就可以在实现类中对获取到的数据继续做一次判空。
   /**
     * 与map相似,要求f返回的值必须是Optional.
     */
    public static void testFlatMap(){
        Optional<Employee> employee = Optional.ofNullable(new Employee("吴国庆",29,999.999));
        Optional<String> s = employee.flatMap(TestOptional::test1);
        System.out.println(s.orElse("张三"));
    }

    public static Optional<String> test1(Employee employee){
        return Optional.ofNullable(employee.getName());
    }

Employee类
public class Employee {

    String name;

    Integer age;

    Double salary;

    Status status;

    public Employee(){
    }

    public Employee(String name, Integer age, Double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Employee(String name, Integer age, Double salary, Status status) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.status = status;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Employee employee = (Employee) o;

        if (name != null ? !name.equals(employee.name) : employee.name != null) return false;
        if (age != null ? !age.equals(employee.age) : employee.age != null) return false;
        if (salary != null ? !salary.equals(employee.salary) : employee.salary != null) return false;
        return status == employee.status;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (age != null ? age.hashCode() : 0);
        result = 31 * result + (salary != null ? salary.hashCode() : 0);
        result = 31 * result + (status != null ? status.hashCode() : 0);
        return result;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", status=" + status +
                '}';
    }

    public enum Status{
        FREE,
        BUSY,
        VOCATION;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值