入门jdk1.8处理空指针API-Optional

news2024/9/26 3:27:24

文章目录

  • 入门`jdk1.8`处理空指针`API`-`Optional`
    • 类图结构
    • 简要说明
    • 常用api
    • 实践操作
    • 应用场景
      • 场景一: 对象不为空,做一些逻辑处理
      • 场景二:对象为空抛异常,或者对象某个字段为空抛指定异常
      • 场景三:级联判空,父节点,子节点,子子属性
      • 场景四:属性为空,默认值赋值

入门jdk1.8处理空指针API-Optional

类图结构

在这里插入图片描述

简要说明

/**
 * A container object which may or may not contain a non-null value.
 * If a value is present, {@code isPresent()} will return {@code true} and
 * {@code get()} will return the value.
 *
 * <p>Additional methods that depend on the presence or absence of a contained
 * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
 * (return a default value if value not present) and
 * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
 * of code if the value is present).
 *
 * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
 * class; use of identity-sensitive operations (including reference equality
 * ({@code ==}), identity hash code, or synchronization) on instances of
 * {@code Optional} may have unpredictable results and should be avoided.
 *
 * @since 1.8
 */

一个可以包含非空值也可以不包含非空值的容器对象。如果一个值存在,isPresent()将返回true和get()将返回值。
构造方法

    /**
     * 空的Optional
     */
    private static final Optional<?> EMPTY = new Optional<>();

    /**
     * If non-null, the value; if null, indicates no value is present
     */
    private final T value;

    /**
     * Constructs an empty instance.
     *
     * @implNote Generally only one empty instance, {@link Optional#EMPTY},
     * should exist per VM.
     */
    private Optional() {
        this.value = null;
    }

常用api

构建空的Optional实例对象

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

构建指定类型的Optional

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

构建非空的对象

    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

构建各种对象,对空对象做了处理

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

获取对应数值对象情况

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

如果具体数值存在,返回true,否则false

    /**
     * Return {@code true} if there is a value present, otherwise {@code false}.
     *
     * @return {@code true} if there is a value present, otherwise {@code false}
     */
    public boolean isPresent() {
        return value != null;
    }

如果Optional存在实例对象,进行逻辑操作,通过Consumer处理

    /**
     * If a value is present, invoke the specified consumer with the value,
     * otherwise do nothing.
     *
     * @param consumer block to be executed if a value is present
     * @throws NullPointerException if value is present and {@code consumer} is
     * null
     */
    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

过滤操作,筛选数据,前提是不能为空

    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

实践操作

        // 创建空的Optional,内部通过构造方法new一个Optional
        Optional<Object> empty = Optional.empty();

        // 根据非空对象创建Optional,如果对象为空,抛异常空指针
        User user = User.builder().userName("小米粒").age(10).build();
        Optional<User> userOptional = Optional.of(user);
        log.info("userOptional : [{}]" , userOptional);
        // userOptional : [Optional[NoDaoTest.User(userName=小米粒, age=10, loginTime=null, account=null)]]

        // 可以接收对象为空
        User nullUser=null;
        Optional<User> nullUserOptional = Optional.ofNullable(nullUser);
        log.info("nullUserOptional : [{}]" , nullUserOptional);
        // nullUserOptional : [Optional.empty]

        // 判断Optional是否包含对象
        boolean userOptionalPresent = nullUserOptional.isPresent();
        log.info("userOptionalPresent : [{}]" , userOptionalPresent);
        // userOptionalPresent : [false]
        boolean userOptionalPresent1 = userOptional.isPresent();
        log.info("userOptionalPresent1 : [{}]" , userOptionalPresent1);
        //  userOptionalPresent1 : [true]

        // 如果Optional包含属性value-》业务数据,可以做一些特殊处理
        userOptional.ifPresent(item->item.setAge(88));
        log.info("如果Optional包含属性value-》业务数据,可以做一些特殊处理 userOptional : [{}]" , userOptional);
        // 如果Optional包含属性value-》业务数据,可以做一些特殊处理 userOptional : [Optional[NoDaoTest.User(userName=小米粒, age=88, loginTime=null, account=null)]]

        // 获取容器中属性,类似于getter方法
        User userTarget = userOptional.get();
        log.info("userTarget : [{}]" , userTarget);
        // userTarget : [NoDaoTest.User(userName=小米粒, age=88, loginTime=null, account=null)]

        // 如果Optional中属性为空,可以创建新的对象返回,不为空正常返回
        User userOrElse = nullUserOptional.orElse(User.builder().userName("笑一笑").build());
        log.info("userOrElse : [{}]" , userOrElse);
        // userOrElse : [NoDaoTest.User(userName=笑一笑, age=null, loginTime=null, account=null)]

        // 如果Optional属性为空,通过Supplier函数创建对象返回,否则返回原始对象
        User userOrElseGet = nullUserOptional.orElseGet(() -> User.builder().userName("唠一唠").build());
        log.info("userOrElseGet : [{}]" , userOrElseGet);
        // userOrElseGet : [NoDaoTest.User(userName=唠一唠, age=null, loginTime=null, account=null)]

        // 如果Optional属性为空,抛出指定异常
        // User userOrElseThrow = nullUserOptional.orElseThrow(() -> new IllegalArgumentException("指定异常抛出信息"));
        // log.info("userOrElseThrow : [{}]" , userOrElseThrow);

        // 过滤操作
        User userFilter = User.builder().userName("过滤名称").build();
        Optional.ofNullable(userFilter)
                .filter(item->StringUtils.equals("过滤名称", item.getUserName()))
                .ifPresent(x->log.info("x : [{}]" , x)
                );
        //  x : [NoDaoTest.User(userName=过滤名称, age=null, loginTime=null, account=null)]

        User userMap = User.builder().userName("map").build();
        Optional.ofNullable(userMap)
                .map(item->{
                    item.setAge(10);
                    return item;
                });
        log.info("userMap : [{}]" , userMap);
        // userMap : [NoDaoTest.User(userName=map, age=10, loginTime=null, account=null)]
        
        

应用场景

场景一: 对象不为空,做一些逻辑处理

// 以前开发
if(userInfo != null){
    userInfo.setProperty("*");
}
// 现在开发
Optional.ofNullable(userMap)
        .ifPresent(item->item.setAge(99));
log.info("场景一:userMap  [{}]" , userMap);
// 场景一:userMap  [NoDaoTest.User(userName=map, age=99, loginTime=null, account=null)]

场景二:对象为空抛异常,或者对象某个字段为空抛指定异常

// 以前开发
if(userInfo != null){
    if(userInfo.getUserName() != null && userInfo.getUserName() != ""){
        // 逻辑处理
    }
}

// 现在开发
// 无论是user为空还是名字为空,抛异常
User userEmpty = User.builder().build();
User nullUser = null;
Optional.ofNullable(userEmpty)
        .filter(item -> StringUtils.isNotBlank(item.getUserName()))
        .orElseThrow(() -> new IllegalArgumentException("对象为空或者姓名为空"))
;

场景三:级联判空,父节点,子节点,子子属性

Student son = Student.builder().build();
User parentUser = User.builder()
        .userName("父节点名称")
        .student(son)
        .build();
Optional.ofNullable(parentUser)
        .map(User::getStudent)
        .map(Student::getStuName)
        .orElseThrow(()->new IllegalArgumentException("子节点不为空或者子节点用户信息不为空"));
     
Optional.ofNullable(parentUser)
   .map(User::getStudent)
   .map(Student::getStuName)
   .orElseThrow(()->new IllegalArgumentException("子节点不为空或者子节点用户信息不为空"));

在这里插入图片描述

场景四:属性为空,默认值赋值

 Optional.ofNullable(userMap)
         .filter(item -> StringUtils.isBlank(item.getUserName()))
         .map(item -> {
             item.setUserName("李华");
             return item;
         });
// 16:19:21.164 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - userMap : [NoDaoTest.User(userName=李华, age=99, loginTime=null, account=null, student=null)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/889755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Control Net】第二章——模型介绍,线稿类

ControlNet1.1版本中发布了15个模型,有点过于多了。这里给分成三类: 线稿类(5个) 线稿类顾名思义,是处理线稿的,或者把图片提取成线稿的。 Canny,硬边缘提取 最早的边缘提取算法,提取的效果已经不如Lineart效果好了,处理有些粗糙。 MLSD,直线检测 可以识别建筑、…

【Linux】查看系统内存命令(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

【Apollo】赋能移动性:阿波罗自动驾驶系统的影响

前言 Apollo (阿波罗)是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 开放能力、共享资源、加速创新、持续共赢是 Apollo 开放平台的口号。百度把自己所拥有的强大、…

Nvidia Jetson 编解码开发(1)介绍

前言 由于项目需要,需要开发Jetson平台的硬件编解码; 优化CPU带宽,后续主要以介绍硬件编解码为主 1.Jetson各平台编解码性能说明 如下是拿了Jetson nano/tx2/Xavier等几个平台做对比; 这里说明的编解码性能主要是对硬件来说的 2. 编解码实现说明 2.1 软件编解码 优点:…

CAS 一些隐藏的知识,您了解吗

目录 ConcurrentHashMap 一定是线程安全的吗 ConcurrentHashMap 在JDK1.8中ConcurrentHashMap 内部使用的是数组加链表加红黑树的结构&#xff0c;通过CASvolatile或synchronized的方式来保证线程安全的,这些原理已毋庸置疑&#xff0c;一言不合上代码. 模拟2个线程累计&#…

I/O软件层次到底是怎么分的?以及对库函数和系统调用的一些联想

其中&#xff0c;设备驱动程序和中断处理程序是直接和硬件打交道的 相关题目&#xff1a; 将系统调用参数翻译成设备操作命令的工作由&#xff08;&#xff09;完成 A. 用户层I/O&#xff1b; B. 设备无关的操作系统软件&#xff1b;C. 中断处理&#xff1b;D. 设备驱动程序 …

vue3 videojs实现播放器,动态更改src

一、背景 vue3下载第三方插件videojs&#xff0c;达到播放器的效果&#xff0c;并且点击事件能够动态更改播放器的src。实现思路&#xff1a; 场景一&#xff1a;只有一个播放器&#xff0c;当点击事件&#xff0c;直接赋值&#xff0c;动态更改封装好的组件的src参数&#xff…

【AI】如何用AI生成XMind思维导图

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff0c;物联网搬砖工一名&#xff0c;致力于为大家淘出更多好用的AI工具&#xff01; 背景 随着人工智能技术的不断发展&#xff0c;越来越多的应用场景开始涉及到AI技术。在办公软件领域&#xff0c;XMind是一款非常受欢迎…

阿里云服务区ECS,申请免费的服务器之后,如何使用xshell 登陆,找不到匹配的host key 算法

目录 1 问题2 解决 1 问题 当在阿里云免费领取服务器之后&#xff0c;使用xshell 登陆不上&#xff0c;提示 找不到匹配的host key 算法 或者 找不到匹配的keyexchange算法 咋解决 2 解决 在在服务器端配置文件&#xff1a;/etc/ssh/sshd_config # 在行尾增加",ecdh…

Linux系统编程:通过System V共享内存实现进程间通信

目录 一. 共享内存实现进程间通信的原理 二. 共享内存相关函数 2.1 共享内存的获取 shmget / ftok 2.2 共享内存与进程地址空间相关联 shmat 2.3 取消共享内存与进程地址空间的关联 shmdt 2.4 删除共享内存 shmctl 2.5 通信双方创建共享内存代码 三. 共享内存实现进程间…

基于java/springboot的考研学习平台

摘 要 本毕业设计的内容是设计并且实现一个考研学习平台。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。考研学习平台的功能已基本实现&#xff0c;主要包括学生、教师、课程信息、学习资源、课程购买、课程发货、课程…

【Spring Boot】构建RESTful服务 — 实战:实现Web API版本控制

实战&#xff1a;实现Web API版本控制 前面介绍了Spring Boot如何构建RESTful风格的Web应用接口以及使用Swagger生成API的接口文档。如果业务需求变更&#xff0c;Web API功能发生变化时应该如何处理呢&#xff1f;可以通过Web API的版本控制来处理。 1.为什么进行版本控制 …

「天锐绿盾」——企业电脑文件加密防泄密软件

随着信息技术的快速发展&#xff0c;公司的日常运营和商业机密都依赖于电脑文件。然而&#xff0c;黑客攻击、员工疏忽或物理丢失等原因都可能导致公司电脑文件泄露&#xff0c;给公司带来巨大的经济损失和声誉损失。因此&#xff0c;公司需要采取有效的措施来保护电脑文件的安…

因数据泄露被罚80万!高校数据安全合规建设如何开展?

8月16日&#xff0c;“南昌网警巡查执法”官方公号披露了一起高校数据泄露事件。 根据通报&#xff0c;南昌某高校3万余条师生个人信息数据在境外互联网上被公开售卖。南昌公安网安部门即刻开展一案双查&#xff0c;抓获犯罪嫌疑人3名&#xff0c;并对涉案高校不履行数据安全保…

游戏IP如何变身数字人?数字人绑定技术了解下

随着数字人的概念大火&#xff0c;各行各业纷纷推出专属的数字人&#xff0c;游戏《王者荣耀》作为国内最大的手游IP&#xff0c;凭借其自有资源角色IP的优势&#xff0c;推出了数字人“上官婉儿”&#xff0c;在晚会上携手真人跨次元演绎歌曲&#xff0c;在动作和舞蹈过程中由…

打造专属照片分享平台:快速上手Piwigo网页搭建

文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;部署piwigo网页前言1.Piwigo2. 使用phpstudy网页运行3. 创建网站4. 开始安装Piwogo 总结 &#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x…

性能分析之MySQL慢查询日志分析

一、背景 MySQL的慢查询日志是MySQL提供的一种日志记录,他用来记录在MySQL中响应的时间超过阈值的语句,具体指运行时间超过long_query_time(默认是10秒)值的SQL,会被记录到慢查询日志中。 慢查询日志一般用于性能分析时开启,收集慢SQL然后通过explain进行全面分析,一…

视频集中存储/云存储/安防监控/视频汇聚平台EasyCVR新增角色权限功能分配

视频集中存储/云存储/安防视频监控/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 EasyCVR视频集中…

解构软件开发中的破窗效应

目录 一、前言 二、解构破窗效应 三、如何解构&#xff1f; 一、前言 “一个房子如果窗户破了&#xff0c;没有人去修补&#xff0c;隔不久&#xff0c;其它的窗户也会莫名其妙地被人打破&#xff1b;一面墙&#xff0c;如果出现一些涂鸦没有被清洗掉&#xff0c;很快的&#x…

dll调用nodejs的回调函数

nodejs使用ffi调用dll。dll中有回调函数调用js中的方法。 c语言中cdll.h文件 extern "C" {typedef void(*JsCall)(int index); //这个就是要传入的类型结构extern __declspec(dllimport) int Add(int a, int b);extern __declspec(dllexport) void CallBackTest(Js…