Optional容器类

Optional类是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好地表达这个概念。并且可以避免空指针异常。

  • Optional.of(T t):创建一个Optional实例。对于该方法,传入的参数一定不能为 null,否则便会抛出 NullPointerException
private final T value;
private Optional(T value) {
        this.value = Objects.requireNonNull(value);
}

public static  Optional of(T value) {
        return new Optional<>(value);
    }
  • Optional.empty():创建一个空的Optional实例。即该 Optional 中不包含值。
private static final Optional EMPTY = new Optional<>();

private Optional() {
        this.value = null;
}

public static Optional empty() {
        @SuppressWarnings("unchecked")
        Optional t = (Optional) EMPTY;
        return t;
}
  • Optional.ofNullable(T t):若 t 不为null,创建Optional实例,否则创建空实例。该方法和 of 方法的区别在于,传入的参数可以为 null。因为该方法会判断传入的参数是否为 null,如果为 null 的话,返回的就是 Optional.empty()。
public static  Optional ofNullable(T value) {
        return value == null ? empty() : of(value);
}
  • get():获取 Optional 包含的值,如果值不存在,如在一个Optional.empty 上调用 get() 方法的话,将会抛出 NoSuchElementException 异常。
public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
  • isPresent():判断是否包含值。
  • orElse(T t):如果调用对象包含值,返回该值,否则返回 t 。
  • orElseGet(Supplier s):当 Optional 中有值的时候,返回值;当 Optional 中没有值的时候,返回从该 Supplier 获得的值。
  • map(Function mapper):如果有值对其处理,然后将返回的值包装在 Optional 中返回,否则返回Optional.empty()。
  • flatMap(Function mapper):与map类似,区别在于,map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用 Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。
  • filter(Predicate p):filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty。

【代码示例】

public class TestOptional {

    @Test
    public void test1(){
        Optional op = Optional.of(new Employee());
        Employee e = op.get();
        System.out.print(e);
    }

    @Test
    public void test2(){
        // 第一行(也就是op.get()之前)就会会产生NullPointException异常,能快速锁定传入的就是空值
        Optional op = Optional.of(null);
        System.out.print(op.get());

        // 构建一个空的Optional,不会产生异常
        Optional op1 = Optional.empty();
        System.out.print(op1.get());

        Optional op2 = Optional.ofNullable(new Employee());
        System.out.print(op2.get());

        // op3.get() 会产生NullPointException异常
        Optional op3 = Optional.ofNullable(null);
        System.out.print(op3.get());
    }

    @Test
    public void test3(){
        Optional op = Optional.ofNullable(null);

        // 判断是否包含值,如果包含则打印
        /*if(op.isPresent()){
            System.out.print(op.get());
        }*/

        // 如果op.get()是空那么就返回默认值,这样就不会产生空指针异常
        Employee emp = op.orElse(new Employee("张三",18,888.9, Employee.Status.FREE));
        System.out.print(emp);
    }

    @Test
    public void test4(){
        Optional op = Optional.ofNullable(null);

        // 函数式接口,可以写任何你想要的功能,而不仅仅是new Employee()
        Employee emp = op.orElseGet(()->new Employee());
        System.out.print(emp);
    }

    @Test
    public void test5(){
        Optional op = Optional.ofNullable(new Employee("张三",18,888.9, Employee.Status.FREE));
        Optional str = op.map((e)->e.getName());
        System.out.print(str.get());  //输出“张三”
    }

    @Test
    public void test6(){
        Optional op = Optional.ofNullable(new Employee("张三",18,888.9, Employee.Status.FREE));
        // flapMap要求返回值为 Optional,进一步避免空指针的影响
        Optional str = op.flatMap((e) -> Optional.of(e.getName()));
        System.out.print(str.get());  //输出“张三”
    }
}

Optional的好处

public class Godness {

    // 女神一定有名字,这样的值就可以不用封装到Optional中
    private String name;

    public Godness(String name) {
        this.name = name;
    }

    public Godness() { }

    public String getName() {
        return name;
    }

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

    private Godness godness;

    public Man() { }

    public Man(Godness godness) {
        this.godness = godness;
    }

    public Godness getGodness() {
        return godness;
    }

    public void setGodness(Godness godness) {
        this.godness = godness;
    }
}
public class NewMan {

    /**
     * 每个男人心中有可能有女神,有可能没有。Optional<>就是封装有可能有有可能没有的值
     *
     * 如果不给Optional对象赋值,那么默认这个Optional对象就是null,就没有意义了,
     * 所以给Optional对象赋值为Optional.empty(),也就是一个空的Optional对象,而不是null
     */
    private Optional godness = Optional.empty();

    public NewMan() {
    }

    public NewMan(Optional godness) {
        this.godness = godness;
    }

    public Optional getGodness() {
        return godness;
    }

    public void setGodness(Optional godness) {
        this.godness = godness;
    }
}
public class TestMan {

    @Test
    public void test1(){
        //产生空指针异常,这个男人没有女神
        Man man = new Man();
        String name = getGodnessName(man);
        System.out.print(name);

        Optional op = Optional.ofNullable(null);
        String str = getGodnessName2(op);  //不能直接传null,会产生NullPointException
        System.out.print(str);
    }

    // 需求:获取一个男人心中女神的名字
    public String getGodnessName(Man man){
        if(man!=null){
            Godness gn = man.getGodness();
            if(gn!=null){
                return gn.getName();
            }
        }
        return "石原里美";
    }

    //传入参数也可能是空值,所以我们也可以用Optional进行封装
    public String getGodnessName2(Optional man){
        return man.orElse(new NewMan())  // 输入参数为空则new 一个男人
                .getGodness()
                .orElse(new Godness("石原里美"))   //没有女神就返回一个默认的女神
                .getName();
    }
}

你可能感兴趣的:(Optional容器类)