• JDK8-10-Optional(1)


    JDK8-10-Optional(1)

    optional 可以避免null,在使用 optional 前看下下面的例子:

    //保险
    public class Insurance {
        private String name;
    
        public String getName() {
            return name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    public class Car {
    
        private Insurance insurance;
    
        public Insurance getInsurance() {
            return insurance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    public class Person {
        private Car car;
    
        public Car getCar() {
            return car;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    定义了三个类,Person Car Insurance ,它们三者关系为 Person -> Car -> Insurance ,现在定义一个方法获取保险名称,如下:

    public class OptionalTest01 {
    
        public static String getCarInsuranceName01(Person person){
            return person.getCar().getInsurance().getName();
        }
    
        public static void main(String[] args) {
            Person person = new Person();
            getCarInsuranceName01(person);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    毫不出意外,程序抛出空指针异常

    Exception in thread "main" java.lang.NullPointerException
    	at com.hs.example.base.jdk8.optional.OptionalTest01.getCarInsuranceName01(OptionalTest01.java:6)
    	at com.hs.example.base.jdk8.optional.OptionalTest01.main(OptionalTest01.java:11)
    
    • 1
    • 2
    • 3

    如何避免程序抛出异常,当有空对象时让方法输出默认值,比较直接的方法便是使用 if 判断:

    public static String getCarInsuranceName02(Person person) {
        if (person != null) {
            Car car = person.getCar();
            if (car != null) {
                Insurance insurance = car.getInsurance();
                if (insurance != null) {
                    return insurance.getName();
                }
            }
        }
        return "";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这种方法嵌套太多,影响程序可读性,也可使用如下方法:

    public static String getCarInsuranceName03(Person person) {
        if (person == null) {
            return "";
        }
        Car car = person.getCar();
        if (car == null) {
            return "";
        }
        Insurance insurance = car.getInsurance();
        if (insurance == null) {
            return "";
        }
        return insurance.getName();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    显然这种方式也不好,return “” 同一段代码出现次数太多,

    使用 optional 解决 null 问题

    如下:仅用一行代码就可以避免 空指针异常并返回默认值

    public static String getCarInsuranceName04(Person person) {
        return Optional.ofNullable(person).map((person1 -> person1.getCar())).map((car -> car.getInsurance())).map(insurance -> insurance.getName()).orElse("");
    }
    
    • 1
    • 2
    • 3

    Optional

    如下 Optional 类包含一个泛型参数 T ,

    public final class Optional {
        /**
         * Common instance for {@code empty()}.
         */
        private static final Optional EMPTY = new Optional<>();
    
        /**
         * If non-null, the value; if null, indicates no value is present
         */
        private final T value;
    
        private Optional() {
            this.value = null;
        }
    
        public static Optional empty() {
            @SuppressWarnings("unchecked")
            Optional t = (Optional) EMPTY;
            return t;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Optional.ofNullable

    通过 ofNullable 方法初始化一个 Optional 对象,当 value(对应上例中 Person,Car 等对象) 为空时返回 EMPTY Optional,

    public static  Optional ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    
    • 1
    • 2
    • 3

    上面一行代码可以分解成这样:

    public static String getCarInsuranceName05(Person person) {
        Optional personOptional = Optional.ofNullable(person);
        Optional carOptional = personOptional.map((person1 -> person1.getCar()));
        Optional insuranceOptional = carOptional.map((car -> car.getInsurance()));
        Optional nameOptional = insuranceOptional.map(insurance -> insurance.getName());
        return nameOptional.orElse("");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    optional.map 方法

    public Optional map(Function mapper) { 
        // 校验 mapper是否为 null ,为 null 直接抛出空指针异常
        Objects.requireNonNull(mapper);
        // 当前 optional 对象 属性value是否为null,为空返回 EMPTY Optional
        if (!isPresent())
            return empty();
        else {
            // 调用 函数式方法(对应上例中 person1.getCar() ),返回 Car 的 Optional 对象
            return Optional.ofNullable(mapper.apply(value));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    isPresent 方法

    public boolean isPresent() {
        return value != null;
    }
    
    • 1
    • 2
    • 3

    如上:map方法接收参数为 函数式方法

    @FunctionalInterface
    public interface Function {
    
        /**
         * Applies this function to the given argument.
         *
         * @param t the function argument
         * @return the function result
         */
        R apply(T t);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    optional.orElse 方法

    对应上例中 Optional nameOptional 的 nameOptional.orElse(“”) 方法,如果 name 不为空则返回 name ,否则返回 “”

    public T orElse(T other) {
        return value != null ? value : other;
    }
    
    • 1
    • 2
    • 3

    例子引用自 Java8 实战第10 章

  • 相关阅读:
    LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
    别说我自私,大牛亲码607页JUC源码分析来了
    虹科新闻 | 22-23财年虹科首席工程师评比结果揭晓
    一文读懂TDengine的三种查询功能
    MVC第三波书店书籍登录展示页面
    如何实现一个安卓群控系统
    java程序设计项目案例化教程题库及答案
    Java-day18(网络编程)
    大咖云集,智慧碰撞|第 18 届 CLK 大会完整议程揭晓(内附报名通道)
    时空数据挖掘四(城市计算)
  • 原文地址:https://blog.csdn.net/sql2008help/article/details/126558651