Optional使用

1.Optional简述

Optional是在java.util包下的一个用于代替null的一个工具类

三个静态方法

Optional.of(T value),该方法通过一个非 null 的 value 来构造一个 Optional,返回的 Optional 包含了 value 这个值。对于该方法,传入的参数一定不能为 null,否则便会抛出 NullPointerException。

    public static  Optional of(T value) {
        return new Optional<>(value);
    }
//========构造方法
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
//===========
     public static  T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

 Optional.ofNullable(T value),传入的参数可以为 null , 该方法会判断传入的参数是否为 null,如果为 null 的话,返回的就是 Optional.empty()。

 public static  Optional ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

 Optional.empty(),该方法用来构造一个空的 Optional,即该 Optional 中不包含值,其实底层实现还是 如果 Optional 中的 value 为 null 则该 Optional 为不包含值的状态

 public static Optional empty() {
        @SuppressWarnings("unchecked")
        Optional t = (Optional) EMPTY;
        return t;
    }

任何访问对象方法或属性的调用都可能导致NullPointerException,为了避免 一般常用 if 判断

  if (!StringUtil.isBlank(rep.getHeadPicture())) {
                xx.setHeadPicture(rep.getHeadPicture());
   }
方法 参数类型 返回类型 说明
get T value为null抛出NoSuchElementException异常
isPresent boolean value为null则返回false
ifPresent Consumer void 如果Optional实例有值则为其调用consumer,否则不做处理
filter Predicate Optional 如果值存在并且满足提供的谓词,就返回包括该值的Optional对象;否则返回一个空的Optional对象
map Function Optional 如果值存在,就对该值执行提供的mapping函数调用,返回Optional对象
flatMap Function> Optional 如果值存在,就对该值执行提供的mapping函数调用,返回非null Optional对象
orElse T T 如果有值则将其返回,否则返回一个默认值
orElseGet Supplier T 如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
orElseThrow Supplier

如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常

2.Optional的相关方法

// 假设有个 User类其中 属性 String name , Integer age;
1.创建实例
User user=null;
 Optional opt=Optional.ofNullable(user);
2.获取值
opt.get();  #如果Optional对象中的值为空,调用get()方法会抛出NoSuchElementException异常
怎么办?先判断

if(opt.isPresent()){ //true,说明有值,Optional对象包含非null值
   //写逻辑
}else{
//没有的逻辑
}
或者 
if(opt.isEmpty){ //true,说明值为null,Optional对象中value=null
   //写无值逻辑
}else{
//有值非null的逻辑
}
3.函数式编程

  //  ifPresent() 在有值非null的条件下,执行消费/函数,若值value=null,函数不执行!
  opt.ifPresent(item-> System.out.println(item.getName())); //输出人的名称
// user不为null,返回user,否则返回 new User("小白",13)
User user1 = Optional.ofNullable(user).orElse(new User("小白",13));

//orElseGet 方法传入的参数为一个 Supplier 接口的实现 —— 当 Optional 中有值的时候,返回值;当 
//Optional 中没有值的时候,返回从该 Supplier 获得的值。
User user1 = Optional.ofNullable(user).orElseGet(()->new User("小白",13));

//orElseThrow 没有值的时候会抛出异常,抛出的异常由传入的 exceptionSupplier 提供
User user1 = Optional.ofNullable(user).orElseThrow(() -> new RunTimeException("该用户不存在!"));

//map value非null,返回一个新的Optional,value为null,返回Optional.empty()
//不为null时,返回新的String类型的name 或 Integer 类型的age, map 方法会使用 //Optional.ofNullable 将其包装为 Optional
Optional username= Optional.ofNullable(user).map(item->item.getName());

//flatMap 不同于 map,value非null,返回函数的值  
String username= Optional.ofNullable(user).flatMap(item->item.getName());
或
Optional username= Optional.ofNullable(user).flatMap(item->Optional.of(item.getName()));
注意:flatMap 与 map的比较!!!

//filter 对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty
Optional  username= Optional.ofNullable(user).filter(item->"小白".equals(item.getName()));



3.orElse()和orElseGet()的不同之处

public static void main(String[] args) {
    MyThread2 thread2 = new MyThread2();
    System.out.println("orElse........");
    Optional.ofNullable(thread2).orElse(createNewString());
    System.out.println("orElseGet........");
    Optional.ofNullable(thread2).orElseGet(()->createNewString());
}
private  static MyThread2 createNewString(){
    System.out.println("新的实例在创建!");
    return new MyThread2();
}
//=================结果对比
orElse........
新的实例在创建!
orElseGet........
//==============

将MyThread2 thread2 = new MyThread2(); 改为 MyThread2 thread2 = null;
其他不改动!
//=================结果对比
orElse........
新的实例在创建!
orElseGet........
新的实例在创建!
//===================

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

4.Optional类的链式方法——借用他人说明

        Optional使用_第1张图片

5.怎么应用 或选择

1.参数传递
public void printUserName(Optional userName) {
    if (userName.isPresent()) {
        System.out.println("User name: " + userName.get());
    } else {
        System.out.println("User name is not available.");
    }
}
2.方法返回值:如果一个方法的返回值可能为空,可以使用 Optional 类型来包装它,以便在调用方处理空值的情况
public Optional getUserName(int userId) {
    // some code to get user name by id
    if (userName != null) {
        return Optional.of(userName);
    } else {
        return Optional.empty();
    }
}

你可能感兴趣的:(java,开发语言)