Optional类

Optional类

Optional是java8中新出现的一个类,最初是源自google gava库。目的是对臭名昭著的NullPointerException的异常做预防性的检查。

Tips:

Optional类的源码比较简单,建议大家在使用前仔细看下。我在下面的会给出简单的使用样例,包括一些代码的使用区别,阅读源码有利理解这些区别存在的本质原因。

创建Optionl实例

  • Optional.empty()

    Optional<User> user = Optional.empty();
    

    构建了一个空的Optional。

  • Optional.of()

    User user = new User("张三","12");
    Optional<User> optionalUser = Optional.of(user);
    

    创建一个含有user值的Optional。

  • Optional.ofNullable()

    User user = new User("张三","12");
    Optional<User> optionalUser = Optional.ofNullable(user);
    

    创建一个含有有user值的Optional。

    tips:

    of()ofNullable() 方法都可以创建包含值的 Optional,但是,如果你把 null 值作为参数传递进去:

    • of() 方法会抛出 NullPointerException
    • ofNullable() 方法会抛出 java.util.NoSuchElementException: No value present

获取Optional值

  • Optional.get()

Optional判空

  • Optional.isPersion()

    Optional.ofNullable(user).isPresent()
    

    如果Optional对象不为空,输出为false,否则输出为true;

  • Optional.ifPersion(Consumer consumer)

    Optional.ofNullable(user).ifPresent(u ->  System.out.println(u.getName()));
    

    如果Optional对象不为空,则会执行后面的lamda表达式。

    Tips:

    **IsPresent()IfPresent()都可以判读Optional对象是否为空,但是不同的是IfPresent()**接受一个Consumer(消费者) 参数,如果对象不是空的,就对执行传入的 Lambda 表达式。这才是Option类的精髓所在,所以不要轻易使用isPresent。否则你的代码和之前Object!=null的语法没有区别;

Optional默认值设置

  • Optional.orElse()

    User ua = new User();
    User user = new User("张三","13");
    User re = Optional.ofNullable(ua).orElse(user)
    

    如果Optional对象为null,就会生成orElse(user)中的user,否则返回原ua

  • Optional.orElseGet()

    User ua = new User();
    User user = new User("张三","13");
    User result = Optional.ofNullable(ua).orElseGet(user);
    

    如果Optional对象为null,就会生成orElseGet(user)中的user,否则返回原ua。

    Tips:

    orElse(),工作方式,如果有值则返回该值,否则返回传递给它的参数值;

    orElseGet()有值的时候返回值,如果没有值,它会执行作为参数传入的 Supplier(供应者) 函数式接口,并将返回其执行结果

    区别:
    原传入的值(ua)为null是这个两个方法没有区别,都生成user;

    但是如果传入的值(ua)不为null,orElse()依旧会生成user类,但是orElseGet()不会。

    在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响。

  • Optional.orElseThrow(Supplier exceptionSupplier)

    User user = null;
    User result = Optional.ofNullable(user)
        .orElseThrow( () -> new IllegalStateException());
    

    如果 user 值为 null,会抛出 orElseThrow中定义好的异常,这里抛出的是IllegalStateException()。这个方法可以让异常处理变的多样,灵活。

Optional值过滤

  • Optional.filter(Predicate predicate)

    Optional<User> result = Optional.ofNullable(user)
                    .filter(u -> u.getName().contains("三"));
    

    filter()中传入一个Predicate对象,根据其结果返回过滤后的实例自身,否则返回一个Optional.empty

Optional值转换

  • Optional.map(Function mapper)

    User user = new User("张三","13");
    Optional<String> result = Optional.ofNullable(user).map(u -> u.getName());
    

    map()中传入一个Function(函数式接口)对象,map()方法将Optional中的包装对象用Function函数进行运算,并包装成新的Optional对象(包装对象的类型可能改变);

    上面的user对象经过map后变为了String对象

  • Optional.flatMap(Function> mapper)

    User user = new User("张三","13");
    Optional<String> result = Optional.ofNullable(user)
    	.flatMap(u->Optional.of("李四"));
    

    Tips:
    flatMap()跟map()方法不同的是,入参Function函数的返回值类型为Optional类型,而不是U类型,这样flatMap()能将一个二维的Optional对象映射成一个一维的对象

Optional的链式调用

Optional的使用除了解决了空指针异常之外,另外一个就是其链式调用。下面写个简单的例子。

public class User {
    private String name;
    private String age;
    private  House house;
    
    ....
}
public class House {
    private String size;
    private String address;
    ...
}
User user = new User("张三","13");
        String result = Optional.ofNullable(user)
                .map(u -> u.getHouse())
                .map(h ->h.getAddress())
                .orElse("没有地址");

END!

你可能感兴趣的:(JAVA,java)