Optional容器类

2018-07-31  本文已影响8人  不知名的蛋挞

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

private final T value;
private Optional(T value) {
        this.value = Objects.requireNonNull(value);
}

public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
private static final Optional<?> EMPTY = new Optional<>();

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

public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
}
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
}
public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

【代码示例】

public class TestOptional {

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

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

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

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

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

    @Test
    public void test3(){
        Optional<Employee> 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<Employee> op = Optional.ofNullable(null);

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

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

    @Test
    public void test6(){
        Optional<Employee> op = Optional.ofNullable(new Employee("张三",18,888.9, Employee.Status.FREE));
        // flapMap要求返回值为 Optional<U>,进一步避免空指针的影响
        Optional<String> 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> godness = Optional.empty();

    public NewMan() {
    }

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

    public Optional<Godness> getGodness() {
        return godness;
    }

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

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

        Optional<NewMan> 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<NewMan> man){
        return man.orElse(new NewMan())  // 输入参数为空则new 一个男人
                .getGodness()
                .orElse(new Godness("石原里美"))   //没有女神就返回一个默认的女神
                .getName();
    }
}
上一篇下一篇

猜你喜欢

热点阅读