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开头不存在

目录
相关文章
|
9天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
33 2
|
3天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
|
2天前
|
数据采集 人工智能 Java
Java产科专科电子病历系统源码
产科专科电子病历系统,全结构化设计,实现产科专科电子病历与院内HIS、LIS、PACS信息系统、区域妇幼信息平台的三级互联互通,系统由门诊系统、住院系统、数据统计模块三部分组成,它管理了孕妇从怀孕开始到生产结束42天一系列医院保健服务信息。
13 4
|
20天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
41 17
|
13天前
|
人工智能 监控 数据可视化
Java智慧工地信息管理平台源码 智慧工地信息化解决方案SaaS源码 支持二次开发
智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三大体系为基础应用,实现全面高效的工程管理需求,满足工地多角色、多视角的有效监管,实现工程建设管理的降本增效,为监管平台提供数据支撑。
31 3
|
12天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
16天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
56 4
|
17天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
35 2
|
18天前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
55 3
|
21天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。