重学JDK8新特性之Optional

简介: 重学JDK8新特性之Optional

以前对NULL的处理


//String userName = "张三";
String userName = null;
if(userName != null){
  System.out.println("字符串的长度:" + userName.length());
}else{
  System.out.println("字符串为空");
}


Optional类


Optional是一个没有子类的工具类,Optional是一个可以为null的容器对象,它的主要作用就是为了避

免Null检查,防止NullpointerException


Optional的基本使用


// 第一种方式 通过of方法 of方法是不支持null的
Optional<String> op1 = Optional.of("zhangsan");
//Optional<Object> op2 = Optional.of(null);
// 第二种方式通过 ofNullable方法 支持null
Optional<String> op3 = Optional.ofNullable("lisi");
Optional<Object> op4 = Optional.ofNullable(null);
// 第三种方式 通过empty方法直接创建一个空的Optional对象
Optional<Object> op5 = Optional.empty();


Optional的常用方法


/**
* Optional中的常用方法介绍
* get(): 如果Optional有值则返回,否则抛出NoSuchElementException异常
* get()通常和isPresent方法一块使用
* isPresent():判断是否包含值,包含值返回true,不包含值返回false
* orElse(T t):如果调用对象包含值,就返回该值,否则返回t
* orElseGet(Supplier s):如果调用对象包含值,就返回该值,否则返回 Lambda表达式的返
回值
*/
Optional<String> op1 = Optional.of("zhangsan");
Optional<String> op2 = Optional.empty();
// 获取Optional中的值
if(op1.isPresent()){
  String s1 = op1.get();
  System.out.println("用户名称:" +s1);
}
if(op2.isPresent()){
  System.out.println(op2.get());
}else{
  System.out.println("op2是一个空Optional对象");
}
String s3 = op1.orElse("李四");
System.out.println(s3);
String s4 = op2.orElse("王五");
System.out.println(s4);
String s5 = op2.orElseGet(()->{
  return "Hello";
});
System.out.println(s5);
Person p = new Person("zhangsan",18);
Optional<Person> op = Optional.of(p);
String name = getNameForOptional(op);
System.out.println("name="+name);
public String getNameForOptional(Optional<Person> op){
  if(op.isPresent()){
    String msg = //op.map(p -> p.getName())
      op.map(Person::getName)
      //.map(p -> p.toUpperCase())
      .map(String::toUpperCase)
      .orElse("空值");
    return msg;
  }
return null;
}


额外补充三个常用的:


获取Optional容器的对象:


  • T orElseThrow(Supplier<? extends X> exceptionSupplier) :如果有值则将其返回,否则抛出由Supplier接口实现提供的异常。


过滤:


  • Optional<T> filter(Predicate<? super <T> predicate):如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。


映射


  • <U>Optional<U> map(Function<? super T,? extends U> mapper):如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。


Optional实战


这部分是通过查阅实际上开发中写法总结出来的,并不是只介绍了Optional的概念,而是融入了实际开发中考虑到的情况,实际上在开发中空指针异常的异常很常见,而灵活的的使用Optional能够很好的避免这种情况。


场景一:


PatientInfo patientInfo = patientInfoDao.getPatientInfoById(consultOrder.getPatientId());
if (patientInfo != null) {
    consultInfoResp.setPatientHead(patientInfo.getHead());
}
// 使用Optional 和函数式编程,一行搞定,而且像说话一样
Optional.ofNullable(patientInfo).ifPresent(p -> consultInfoResp.setPatientHead(p.getHead()));


场景二:


public void test1() throws Exception {
    Student student = new Student(null, 3);
    if (student == null || isEmpty(student.getName())) {
        throw new Exception();
    }
    String name = student.getName();
    // 业务省略...
    // 使用Optional改造
    Optional.ofNullable(student).filter(s -> !isEmpty(s.getName())).orElseThrow(() -> new Exception());
}
public static boolean isEmpty(CharSequence str) {
    return str == null || str.length() == 0;
}


场景三:


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.");
}

这个在开发中是很常见的一种逻辑。去判读传进来的参数时候为空,或者是从数据库中获取的对象。由于某些原因,我们不能很流程的直接这样写。

comp.getResult().getChampion().getName()

上面的写法用Optional改写:

public static String getChampionName(Competition comp) throws IllegalArgumentException {
    return Optional.ofNullable(comp)
            .map(Competition::getResult)  // 相当于c -> c.getResult(),下同
            .map(CompResult::getChampion)
            .map(User::getName)
            .orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}


场景四:


int timeout = Optional.ofNullable(redisProperties.getTimeout())
            .map(x -> Long.valueOf(x.toMillis()).intValue())
            .orElse(10000);


目录
相关文章
|
8天前
|
安全 JavaScript 前端开发
JDK1.8的重要的新特性与功能
Java Development Kit (JDK) 1.8,也称为Java 8,是Java平台的一个重大更新,于2014年3月发布。它引入了多项新特性、新的API和性能提升
104 3
|
8天前
|
监控 安全 Java
探索Java的未来:JDK 18新特性全览
探索Java的未来:JDK 18新特性全览
87 0
|
8天前
|
缓存 安全 Java
JDK 14全景透视:每个Java开发者必知的新特性
JDK 14全景透视:每个Java开发者必知的新特性
57 0
|
8天前
|
JavaScript 前端开发 安全
Java新纪元:一探JDK 15的全新特性
Java新纪元:一探JDK 15的全新特性
49 0
|
8天前
|
JSON Java API
探秘JDK 13的黑科技:新特性一览
探秘JDK 13的黑科技:新特性一览
53 0
|
8天前
|
Java 测试技术 API
深度剖析JDK 11全新特性:编程艺术的巅峰之作
深度剖析JDK 11全新特性:编程艺术的巅峰之作
50 0
|
8天前
|
存储 Java 数据管理
探秘JDK 10:崭新特性悉数解析
探秘JDK 10:崭新特性悉数解析
67 0
|
8天前
|
JSON 编解码 Java
Java升级:JDK 9新特性全面解析“
Java升级:JDK 9新特性全面解析“
75 0
|
8天前
|
算法 Java 编译器
升级指南之JDK 11+ 新特性和AJDK
本文详细介绍了JDK个版本之间的特性、区别以及JDK版本更迭时优化了哪些地方,对JDK的版本选择给出了建议,以及升级教程。
|
8天前
|
存储 安全 Java
JDK22发布了!来看看有哪些新特性
以上是介绍 JDK22新特性的全部内容了,突然V哥想要感慨一下,技术之路,学无止境,选择 IT 技术,作个纯粹的人,享受研究技术的过程,这种带来的快感,也许只有真正热爱编程的人才能有体会。