Java源码类-Optional类源码分析与使用

简介: Java源码类-Optional类源码分析与使用

Java源码类-Optional类源码分析与使用

Optional 是 Java8 提供的了 为了解决 Null 安全问题的一个 API 。善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅 。

在阿里巴巴编码规范里面有一段说明:

【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:

正例:使用 JDK8 的 Optional 类来防止 NPE 问题。

一、Optional 类源码-基本方法 [of、empty、ofNullable、get等]

public final class Optional<T> {
    private static final Optional<?> EMPTY = new Optional<>(null);
    private final T value;
    //创建一个空Optional实例
    public static<T> Optional<T> empty() {
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    //传入值构造函数
    private Optional(T value) {
        this.value = value;
    }
    //创建一个Optional实例
    public static <T> Optional<T> of(T value) {
        return new Optional<>(Objects.requireNonNull(value));
    }
    //若 value 不为null,创建Optional实例,否则创建空实例
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? (Optional<T>) EMPTY
                             : new Optional<>(value);
    }
    //获取Optional值,如为Null 抛出异常 NoSuchElementException
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
    //判断是否包含值  True = 包含值   Flase = 不包含值
    public boolean isPresent() {
        return value != null;
    }
    //判断是否为空  True = 不包含值   Flase = 包含值
    public boolean isEmpty() {
        return value == null;
    }
    //如果存在一个值,则使用该值执行给定的操作,否则不执行任何操作
    public void ifPresent(Consumer<? super T> action) {
        if (value != null) {
            action.accept(value);
        }
     }
    //如果存在值,则使用该值执行给定的操作,否则执行给定的基于空的操作
    public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
        if (value != null) {
            action.accept(value);
        } else {
            emptyAction.run();
        }
    }
    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent()) {
            return this;
        } else {
            return predicate.test(value) ? this : empty();
        }
    }
}

二、Optional 类源码-方法 [map、flatMap、filter、stream等]

2.1.1 map简介

如果存在一个值,则返回一个Optional描述(就像通过ofNullable)将给定映射函数应用于该值的结果,否则返回一个空的Optional。

如果映射函数返回空结果,则此方法返回空的Optional。

2.1.2 map源码
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            return Optional.ofNullable(mapper.apply(value));
        }
 }
2.1.3 演示
public void runOptionalMap() {
        Optional<String> optSetting = Optional.of("This is Project");
        Optional<String> optConcat =optSetting.map(value->value.concat(" Concat Project"));
        System.out.println(optConcat.get());
}
运行结果:
This is Project Concat Project
2.2.1 flatMap简介

如果存在值,则返回将给定的可选映射函数应用于该值的结果,否则返回空的可选值。这个方法类似于map(Function),但是映射函数的结果已经是一个Optional,如果调用,flatMap不会将它包装在一个额外的Optional中。

2.2.2 map源码
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);
            return Objects.requireNonNull(r);
        }
}
2.1.3 演示
public void  runOptionalFlatMap(){
        Optional<String> optSetting = Optional.of("This is Project");
        Optional<String> optConcat =optSetting.flatMap(v->Optional.ofNullable(v.concat(" Concat FlatMap")));
        System.out.println(optConcat.get());
 }
运行结果:
This is Project Concat FlatMap
2.3.1 filter简介

如果存在一个值,并且该值与给定的谓词匹配,则返回描述该值的Optional,否则返回空Optional。

2.3.1 filter源码
public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent()) {
            return this;
        } else {
            return predicate.test(value) ? this : empty();
        }
  }
2.3.3 演示
public void runOptionalFilter(){
     Optional<String> optSetting = Optional.of("This is Project");
     Optional<String> optConcatFilter =optSetting.filter(v->v.charAt(0)=='C');
     if(optConcatFilter.isEmpty()){
        System.out.println("字符串已C开头不存在");
     }else{
         System.out.println("字符串已C开头存在");
     }
 }
运行结果:
字符串已C开头不存在

目录
相关文章
|
3月前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
95 7
|
4天前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:输入与输出:Scanner与System类
你是否也经历过这些崩溃瞬间?三天教程连`i++`和`++i`都说不清,面试时`a==b`与`equals()`区别大脑空白,代码总是莫名报NPE。这个系列就是为你打造的Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可学习。直击高频考点和实际开发中的“坑位”,拒绝冗长概念,每篇都有可运行代码示例。涵盖输入输出基础、猜数字游戏、企业编码规范、性能优化技巧、隐藏技能等。助你快速掌握Java核心知识,提升编程能力。点赞、收藏、转发,助力更多小伙伴一起成长!
34 19
|
8天前
|
前端开发 JavaScript Java
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
50 17
|
5天前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
36 11
|
11天前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
|
11天前
|
存储 Java 编译器
课时11:综合实战:简单Java类
本次分享的主题是综合实战:简单 Java 类。主要分为两个部分: 1.简单 Java 类的含义 2.简单 Java 类的开发
|
12天前
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
34 5
|
11天前
|
Oracle Java 关系型数据库
课时37:综合实战:数据表与简单Java类映射转换
今天我分享的是数据表与简单 Java 类映射转换,主要分为以下四部分。 1. 映射关系基础 2. 映射步骤方法 3. 项目对象配置 4. 数据获取与调试
|
15天前
|
Java 调度
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
83 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
|
1月前
|
JavaScript 安全 Java
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
48 12

热门文章

最新文章