Java 8 Optional 的用法

    认识Optional     

Optionals是用于防止 NullPointerException 的漂亮工具。让我们快速了解一下Optionals的工作原理。

Optional 是一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是有时却什么也没有返回,而在Java 8中,你应该返回 Optional 而不是 null。

        可以大概瞥一眼官方文档:https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

先看几个传统if判空用法:

public static String getName(User u) {
    if (u == null || u.name == null)
        return "Unknown";
    return u.name;
}

public static String getChampionName(Competition comp) throws IllegalArgumentException {
    if (comp != null) {
        CompResult result = comp.getResult();
        if (result != null) {
            User champion = result.getChampion();
            if (champion != null) {
                return champion.getName();
            }
        }
    }
    throw new IllegalArgumentException("The value of param comp isn't available.");
}
Optional改写:
public static String getName(User u) {
    return Optional.ofNullable(u)
                    .map(user->user.name)
                    .orElse("Unknown");
}

public static String getChampionName(Competition comp) throws IllegalArgumentException {
    return Optional.ofNullable(comp)
            .map(c->c.getResult())
            .map(r->r.getChampion())
            .map(u->u.getName())
            .orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}

是不是看着很简洁舒服,可读性也提高了一个档次。

核心常用方法介绍:

如何生成一个Optenal对象?

 Optional<String> s2 = Optional.ofNullable(s);// Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.  

Optional<Object> empty = Optional.empty();//Returns an empty Optional instance.
//of():为非null的值创建一个Optional
Optional<String> optional = Optional.of("bam");
// isPresent(): 如果值存在返回true,否则返回false
optional.isPresent();           // true
//get():如果Optional有值则将其返回,否则抛出NoSuchElementException
optional.get();                 // "bam"
//orElse():如果有值则将其返回,否则返回指定的其它值
optional.orElse("fallback");    // "bam"
//ifPresent():如果Optional实例有值则为其调用consumer,否则不做处理
optional.ifPresent((s) -> System.out.println(s.charAt(0)));     // "b"

一般使用Optional.ofNullable(s) 即可 ,返回一个不确定的Optional。

 map ()  映射出一个对象放入Optional容器。

 Optional<String> s = Optional.ofNullable(Arrays.asList("1,2,3".split(",")))
                .map(li -> li.get(0));
String s3 = Optional.ofNullable(Arrays.asList("1,2,3".split(",")))
.map(li -> li.get(0))
.orElse("4");
.filter()过滤出符合条件的
List<String> list==Optional.ofNullable(Arrays.asList("1,2,3".split(","))) .filter(str->str.equals("2")).orElseThrow(()->new IllegalArgumentException("IllegalArgument"));

 

 

Optional.filter() 可以用于参数校验 如:
public void setName(String name) throws IllegalArgumentException {
    this.name = Optional.ofNullable(name).filter(User::isNameValid)
                        .orElseThrow(()->new IllegalArgumentException("Invalid username."));
}

 

 

Optional就像一个处理不确定性的管道,我们在一头丢进一个可能是null的东西(接口返回结果),经过层层处理,最后消除不确定性。Optional在过程中保留了不确定性,从而把对null的处理移到了若干次操作的最后,以减少出现NPE错误的可能。

于是,Optional应用的建议也呼之欲出了:

  1. 适用于层级处理(依赖上一步操作)的场合。
  2. 产生对象的方法若可能返回null,可以用Optional包装。
  3. 尽可能延后处理null的时机,在过程中使用Optional保留不确定性。
  4. 尽量避免使用Optional作为字段类型。

这种依赖上一步的操作也叫Continuation。而Optional的这种接受并组合多个Continuation的设计风格就是Continuation-passing style(CPS)。

posted @ 2019-12-03 16:33  千里送e毛  阅读(685)  评论(0)    收藏  举报