JDK1.8新特性---Optional容器类

一、Optiona容器类说明

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

二、Optional容器类常用方法说明

常用方法:
Optional.of(T t):创建一个Optional实例
Optional.empty():创建一个空的Optional实例
Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空的实例
isPresent():判断是否包含值
orElse(T t):如果Optional实例包含值,返回该值,否则返回t
orElseGet(Supplier s):如果Optional实例包含值,返回该值,否则返回s获取的值
map(Function f):如果有值对其处理,并返回成立后的Optional,否则返回Optional.empty()
flatMap(Function mapper):与map类似,要求返回值必须是Optional

三、Optional部分容器类的源码分析

//这是Optional类中的两个变量
//EMPTY表示一个空的Optional实例,所包含的值为null
private static final Optional<?> EMPTY = new Optional<>();

//Optional实例所包含的值
private final T value;


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

//创建一个空的Optional实例
public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}

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

//创建一个Optional实例
public static <T> Optional<T> of(T value) {
    return new Optional<>(value);
}

//若t不为null,创建Optional实例,否则创建空的实例
public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}

//得到Optional类实例所包含的值
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

//判断是否包含值
public boolean isPresent() {
    return value != null;
}

//如果有值对其处理,并返回成立后的Optional,否则返回Optional.empty()
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}

//与map类似,要求返回值必须是Optional
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value));
    }
}

//如果Optional实例包含值,返回该值,否则返回t
public T orElse(T other) {
    return value != null ? value : other;
}

//如果Optional实例包含值,返回该值,否则返回s获取的值
public T orElseGet(Supplier<? extends T> other) {
    return value != null ? value : other.get();
}

四、演示

public class OptionalAPI {
    @Test
    public void test01(){
        //Optional.of(T t):创建一个Optional实例
        Optional<Employee> optional = Optional.of(new Employee());
        Employee employee = optional.get();
        System.out.println(employee);
    }

    @Test
    public void test02(){
        //Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空的实例
        Optional<Object> optional = Optional.ofNullable(null);
        //isPresent():判断是否包含值
        if (optional.isPresent()){
            System.out.println("值是:"+optional.get());
        }
        //orElse(T t):如果调用对象包含值,返回该值,否则返回t
        System.out.println(optional.orElse(new Employee("张三",22,9999.99)));
        //orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值
        Employee o = (Employee) optional.orElseGet(Employee::new);
        System.out.println(o);
    }

    @Test
    public void test03(){
        //map(Function f):如果有值对其处理,并返回成立后的Optional,否则返回Optional.empty()
        Optional<Employee> optional = Optional.of(new Employee("张三", 22, 9999.99));
        Optional<String> optionalS = optional.map(Employee::getName);
        System.out.println(optionalS.get());
        //flatMap(Function mapper):与map类似,要求返回值必须是Optional
        Optional<String> stringOptional = optional.flatMap((e) -> Optional.of(e.getName()));
        System.out.println(stringOptional.get());
    }
}

五、在真实的场景中使用Optional类

例如:每个男人心中都有一个女神,每个女神都有一个名字。但是不是每个男人心中都有女神,有可能他们心中有男神,也有可能什么都没有,但是每一个女神肯定都有名字。
根据上面的场景就得出两个类:

public class Man {
    private Godness godness;
    public Man(){}

    public Godness getGodness() {
        return godness;
    }

    public void setGodness(Godness godness) {
        this.godness = godness;
    }
}
public class Godness {
    private String name;
    public Godness(){

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

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

现在我想根据一个男人得到他的女神的名字,但是这个男人根本没有女神,然后就会得到空指针异常。

public void test(){
    Man man = new Man();
    String name = getGodnessName1(man);
    System.out.println(name);
}
//原始解决办法
private String getGodnessName1(Man man){
    if (man != null){
        Godness godness = man.getGodness();
        if (godness != null){
            return godness.getName();
        }
    }
    return "苍老师";
}
//用Optional类解决办法
private String getGodnessName2(Optional<Man> man){
    return Optional.ofNullable(man.orElse(new Man()).getGodness())
            .orElse(new Godness("苍老师"))
            .getName();
}
//这就是另外一种解决方法
private String getGodnessName3(Optional<NewMan> newMan){
    return newMan.orElse(new NewMan())
            .getGodness()
            .orElse(new Godness("苍老师"))
            .getName();
}

还有一种解决办法,就是直接在Man类中把Godness用Optional类封装起来

public class NewMan {
    private Optional<Godness> godness=Optional.empty();
    public NewMan(){}

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

    public void setGodness(Optional<Godness> godness) {
        this.godness = godness;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值