当前位置: 首页 > article >正文

Java8 新特性 —— Optional API 详解

本文涉及到的知识点有Lambda表达式,函数式接口以及Stream API,有不了解的小伙伴可以先学习前两篇文章:
Java8 新特性 —— Lambda 表达式、函数接口以及方法引用详解
Java8 新特性 —— Stream API 详解

前言

Optional类是Java8新引进的一个主要用于解决的问题是空指针异常(NullPointerException)的一个类。
本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。
Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。但是 Optional 的意义显然不止于此。

在以往的开发过程中,要想排除空指针问题,就得用到大量的if…else…判断。举个例子,有一个班级,班级有若干名学生:

class Clazz{
    private List<Student> students;
}

class Student {
    private String id;
    private String name;
}

获取一个班级学号为一的学生姓名:

//获取一个班级学号为一的学生姓名
public String getName(Clazz clazz){
    if (clazz != null){
        List<Student> students = clazz.students;
        if (students != null){
            for (Student stu : students) {
                if ("1".equals(stu.id)){
                    return stu.name;
                }
            }
        }
    }
    return "未找到该学生";
}

在学习了前两篇Lambda表达式,以及Stream API 加上本篇的Optional API 就可以这么写:

//获取一个班级学号为一的学生姓名
public String getName(Clazz clazz){
    return Optional.ofNullable(Optional.ofNullable(clazz).orElse(new Clazz()).students).orElse(new ArrayList<>())
            .stream().filter(student -> student != null && "1".equals(student.id))
            .map(student -> student.name)
            .findFirst().orElse("未找到该学生");
}

传统的if…else…消失不见,代码也随之变得简洁优雅,下面我们来详细聊聊Optional API。

一、创建 Optional 实例

  • Optional.of(T t):创建一个 Optional 实例,t 不为空,否则也会报空指针;
  • Optional.ofNullable(T t):若 t 不为 null,创建Optional 实例,否则创建空实例;
  • Optional.empty():创建一个空的Optional实例。
@Test
public void test1(){
    //Optional.of(T t) 创建一个 Optional实例, 传入的值为空也会出现空指针
    Optional<String> o1 = Optional.of("值不为空");
    System.out.println("Optional.of() 值不为空: " + o1);

    try {
        Optional<String> o2 = Optional.of(null);
        System.out.println("Optional.of() 值为空: " + o2);
    } catch (Exception e) {
        System.out.println("Optional.of(null)" + e.getClass().getSimpleName());
    }

    //若 t 不为 null,创建 Optional 实例,否则创建空实例
    Optional<Object> o3 = Optional.ofNullable(null);
    System.out.println("Optional.ofNullable() 值为空: " + o3);

    //Optional.empty(), 创建一个空的 Optional 实例
    Optional<Object> o4 = Optional.empty();
    System.out.println("Optional.empty(): " + o4);
}

运行效果图如下:

在这里插入图片描述


二、Optional 的基本使用

  • isPresent():判断是否包含值;
  • get():取出Optional 里的值,需要判断是否有值,否则没值会抛出NoSuchElementException(表明请求的元素不存在);
  • orElse(T t):如果调用对象包含值,返回该值,否则返回t;
  • orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回 s 获取的值(自定义方法取值)。

(1)判断是否有值与取值

@Test
public void test2(){
    List<String> list = Arrays.asList("Java", "Lambda", "Function", "Stream", "Optional");
    //判断集合是否包含 "Optional"
    Optional<String> notNullOpt = list.stream().filter(s -> "Optional".equals(s)).findFirst();

    //isPresent()判断是否有值
    System.out.println("集合是否有值: " + notNullOpt.isPresent());

    //get()取出Optional里的值,需要先判断是否有值,否则也会抛出NullPointerException异常
    //取出集合中第一个元素
    if (notNullOpt.isPresent()){
        System.out.println("集合中存在: " + notNullOpt.get());
    }

    System.out.println("======以下为没值, 没判断是否有值======");
    Optional<String> nullOpt = list.stream().filter(s -> "null".equals(s)).findFirst();
    try {
        System.out.println(nullOpt.get());
    } catch (Exception e) {
        System.out.println("Optional 中为空, 没判断是否有值, 打印报错" + e.getClass().getSimpleName());
    }
}

运行效果图如下:

在这里插入图片描述

(2)orElse() 的使用

@Test
public void test3(){
    //orElse(T t), 如果调用对象包含值,返回该值,否则返回 t
    Optional<String> o1 = Optional.ofNullable(null);
    Optional<String> o2 = Optional.ofNullable("值不为空");
    String s1 = o1.orElse("值为空");
    String s2 = o2.orElse("值为空");
    System.out.println("Optional.ofNullable(null) 取值: " + s1);
    System.out.println("Optional.ofNullable(值不为空) 取值: " + s2);
}

运行效果图如下:

在这里插入图片描述

(3)orElseGet() 的使用

@Test
public void test4(){
    //orElseGet(T t), 如果调用对象包含值, 返回该值, 否则返回 t (由Lambda表达式指定)
    Optional<String> o1 = Optional.ofNullable(null);
    Optional<String> o2 = Optional.ofNullable("值不为空");
    String s1 = o1.orElseGet(() -> "值为空");
    String s2 = o2.orElseGet(() -> "值为空");
    System.out.println("Optional.ofNullable(null) 取值: " + s1);
    System.out.println("Optional.ofNullable(值不为空) 取值: " + s2);
}

运行效果图如下:

在这里插入图片描述

总结

  • Optional 可以有效避免java开发中的NullPointerException问题;
  • 创建Optional 主要通过 of()和ofNullable()方法
    • of()方法一般在确定有值,获取某个特定值时使用,如果为空也会报NullPointerException
    • ofNullable()一般在不确定是否有值时,配合orElse()如果没值就设定一个默认值使用
  • isPresent()判断是否有值
  • get() 方法从Optional 中取值
    • 需要先isPresent()判断是否有值,如果没值则会抛出NoSuchElementException异常
  • orElse()和orElseGet()在Optional 为空时,指定默认值
    • orElseGet()为Lambda表达式生成数据,一般orElse()就够用

http://www.kler.cn/a/379842.html

相关文章:

  • 自研小程序-心情追忆
  • 数字后端零基础入门系列 | Innovus零基础LAB学习Day8
  • Java环境下配置环境(jar包)并连接mysql数据库
  • ICPC区域赛成都站【赛后回顾+总结】
  • RHCSA课后练习3(网络与磁盘)
  • AI打造超写实虚拟人物:是科技奇迹还是伦理挑战?
  • 《GAN 的基本原理》
  • 【Nextcloud】在 Ubuntu 22.04.3 LTS 上的 Nextcloud Hub 8 (29.0.0) 优化
  • Copilot功能
  • 在.net下后台设置前台UEditor编辑器不可编辑
  • WordPress网站添加嵌入B站视频,自适应屏幕大小,取消自动播放
  • Spring Boot框架:校园社团信息管理的现代化解决方案
  • SQL 数据结构查询
  • Python网络爬虫:入门与实战
  • GHuNeRF: Generalizable Human NeRF from a Monocular Video
  • ubunu安装官方微信 解决安装后更新系统变为atzlinux的问题 卸载微信
  • 基于python flask的知乎问答文本分析与情感预测系统
  • 让Erupt框架支持.vue文件做自定义页面模版
  • QT中QML例程-学习笔记-语法
  • N-155基于springboot,vue宿舍管理系统
  • 【docker compose】docker compose的hello world
  • 第100+31步 ChatGPT学习:概率校准 Quantile Calibration
  • UI自动化测试 —— CSS元素定位实践!
  • CSS 计数器:深入解析与高级应用
  • flutter区别于vue的写法
  • CTF解题实录——2024年网鼎杯白虎赛道Misc04