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

Java中的Optional

在我们日常的开发中,我们经常会遇到 NullPointerException。如何才能优雅的处理NPE?这里告诉大家一个较为流行的方法

java.util.Optional

使用Optional来修饰对象,表示这个对象可能为null。在使用时,就要加以注意,必须要考虑该值为null的场景。

使用Optional构建对象

// 创建一个空的car
        Optional<Car> car = Optional.empty();

        // 使用of创建,of的值一定不能是null,否则赋值阶段就报 NullPointerException
        /**
         *  if (obj == null)
         *             throw new NullPointerException();
         */
        Car car1 = new Car();
        Optional<Car> ocar1 = Optional.of(car1);

        // 创建一个可以为null的Optional,该方法支持car为null,但是会在用到car的地方抛出异常,但不是空指针异常。
        Car car2 = new Car();
        Optional<Car> ocar2 = Optional.ofNullable(car2);
        System.out.println(ocar2.get());
        Optional<Car> ocar22 = Optional.ofNullable(null);

获取Optional中的对象

  1. get: 这是最不安全的方法。如果变量存在就返回,不存在的话则会抛出NoSuchElementException的异常。所以,get()的使用场景一定是十分确定Optional修饰的值一定是有内容的,否则不建议使用。
/**
         * public T get() {
         *         if (value == null) {
         *             throw new NoSuchElementException("No value present");
         *         }
         *         return value;
         *     }
         */
        String name = car.getInsurance().get().getName();
        System.out.println(name);
  1. orElse: 作用和get一样,但是没有值时可以使用默认值
/**
         *     public T orElse(T other) {
         *         return value != null ? value : other;
         *     }
         */
        String orName = car.getInsurance().orElse(new Insurance()).getName();
        System.out.println(orName);
  1. orElseGet: orElse的延时版本。只有当val为空时,才会创建defleat value
/**
         * public T orElseGet(Supplier<? extends T> supplier) {
         *         return value != null ? value : supplier.get();
         *     }
         */
        String getElseName = car.getInsurance().orElseGet(Insurance::new).getName();
        System.out.println("getElseName " + getElseName);
  1. orElseThrow: 和orElse类似,只是当value不存在时抛出异常
public T orElseThrow() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
  1. ifPresent: 判断值存在之后再操作,不存在就不操作
/**
         * public void ifPresent(Consumer<? super T> action) {
         *         if (value != null) {
         *             action.accept(value);
         *         }
         *     }
         */
        car.getInsurance().ifPresent(ins -> {
            String pname = ins.getName();
            System.out.println("inPresent " + pname);
        });

Optional 中map和flatmap的差别

Optional<Optional<Car>> mCar = optionalPerson.map(Person::getCar);
Optional<Car> flatMapCap = optionalPerson.flatMap(Person::getCar);

map

public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            //  返回值使用Optional包装
            return Optional.ofNullable(mapper.apply(value));
        }
    }

flatMap

public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            @SuppressWarnings("unchecked")
            Optional<U> r = (Optional<U>) mapper.apply(value);
            // 返回值没有包装,直接是Optional对象,只做了一次判null
            return Objects.requireNonNull(r);
        }
    }

相关文章:

  • 五个人的五个成绩
  • 金仓数据库KingbaseES数据库参考手册(服务器配置参数6. 预写式日志)
  • 通过jsoncpp读取JSON文件
  • chrome 开启HEVC硬件解码
  • 企业初创如何搭建自己的官方网站?
  • JavaScript重点知识总结一
  • 集合篇---Map集合
  • 【秋招笔经】大厂笔试题1
  • TiFlash 源码阅读(九)TiFlash 中常用算子的设计与实现
  • C/C++教程 从入门到精通《第二十七章》——脚本开发
  • SAP Fiori Elements SmartLink 创建实例的单步调试
  • 【计算机网络—TCP相关】| 三次握手+四次挥手(面试不慌)
  • c# 与modbus
  • Java Character.SubSet hashCode()方法具有什么功能呢?
  • 【办公类-06】python批量制作代班排班表
  • $translatePartialLoader加载失败及解决方式
  • 【面试系列】之二:关于js原型
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Apache的80端口被占用以及访问时报错403
  • in typeof instanceof ===这些运算符有什么作用
  • Javascript弹出层-初探
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • React组件设计模式(一)
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • Webpack 4 学习01(基础配置)
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 问题之ssh中Host key verification failed的解决
  • 小试R空间处理新库sf
  • 学习笔记:对象,原型和继承(1)
  • 最近的计划
  • ​queue --- 一个同步的队列类​
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (ZT)出版业改革:该死的死,该生的生
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • .java 9 找不到符号_java找不到符号
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net 后台导出excel ,word
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .Net的C#语言取月份数值对应的MonthName值
  • .NET下的多线程编程—1-线程机制概述
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • [20150707]外部表与rowid.txt
  • [ArcPy百科]第三节: Geometry信息中的空间参考解析
  • [bzoj1901]: Zju2112 Dynamic Rankings
  • [Django 0-1] Core.Checks 模块
  • [flask]http请求//获取请求体数据
  • [GDMEC-无人机遥感研究小组]无人机遥感小组-000-数据集制备
  • [java/jdbc]插入数据时获取自增长主键的值
  • [jQuery]div滚动条回到最底部
  • [JS入门到进阶] 哎,被vite小坑了一波,大家记得配置build.cssTarget为‘chrome61‘
  • [Oh My C++ Diary]return 1和return 0的区别
  • [Python人工智能] 四十.命名实体识别 (1)基于BiLSTM-CRF的威胁情报实体识别万字详解