Optional使用

1.Optional简述

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

三个静态方法

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

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

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

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

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

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

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

  if (!StringUtil.isBlank(rep.getHeadPicture())) {
                xx.setHeadPicture(rep.getHeadPicture());
   }
方法参数类型返回类型说明
getTvalue为null抛出NoSuchElementException异常
isPresentbooleanvalue为null则返回false
ifPresentConsumer<? super T>void如果Optional实例有值则为其调用consumer,否则不做处理
filterPredicate<? super T>Optional<T>如果值存在并且满足提供的谓词,就返回包括该值的Optional对象;否则返回一个空的Optional对象
mapFunction<? super T, ? extends U>Optional<U>如果值存在,就对该值执行提供的mapping函数调用,返回Optional<U>对象
flatMapFunction<? super T, Optional<U>>Optional<U>如果值存在,就对该值执行提供的mapping函数调用,返回非null Optional对象
orElseTT如果有值则将其返回,否则返回一个默认值
orElseGetSupplier<? extends T>T如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
orElseThrowSupplier<? extends X><X extends Throwable>

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

2.Optional的相关方法

// 假设有个 User类其中 属性 String name , Integer age;
1.创建实例
User user=null;
 Optional<User> 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<String> username= Optional.ofNullable(user).map(item->item.getName());

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

//filter 对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty
Optional<String>  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类的链式方法——借用他人说明

        

5.怎么应用 或选择

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

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值