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

目录
相关文章
|
7天前
|
运维 Java
Java版HIS系统 云HIS系统 云HIS源码 结构简洁、代码规范易阅读
云HIS系统分为两个大的系统,一个是基层卫生健康云综合管理系统,另一个是基层卫生健康云业务系统。基层卫生健康云综合管理系统由运营商、开发商和监管机构使用,用来进行运营管理、运维管理和综合监管。基层卫生健康云业务系统由基层医院使用,用来支撑医院各类业务运转。
31 5
|
6天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
33 3
|
1天前
|
Java 编译器 API
Java基础教程(17)-Java8中的lambda表达式和Stream、Optional
【4月更文挑战第17天】Lambda表达式是Java 8引入的函数式编程特性,允许函数作为参数或返回值。它有简洁的语法:`(parameters) -> expression 或 (parameters) ->{ statements; }`。FunctionalInterface注解用于标记单方法接口,可以用Lambda替换。
|
2天前
|
人工智能 安全 Java
Java8 - LocalDateTime时间日期类使用详解
Java8 - LocalDateTime时间日期类使用详解
|
2天前
|
搜索推荐 前端开发 Java
java医院绩效考核管理系统项目源码
系统需要和his系统进行对接,按照设定周期,从his系统获取医院科室和医生、护士、其他人员工作量,对没有录入信息化系统的工作量,绩效考核系统设有手工录入功能(可以批量导入),对获取的数据系统按照设定的公式进行汇算,且设置审核机制,可以退回修正,系统功能强大,完全模拟医院实际绩效核算过程,且每步核算都可以进行调整和参数设置,能适应医院多种绩效核算方式。
6 0
|
3天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
3天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
3天前
|
安全 Java 程序员
|
3天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
3天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式