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

目录
相关文章
|
6月前
|
安全 Java 开发者
告别NullPointerException:拥抱Java Optional
告别NullPointerException:拥抱Java Optional
|
5月前
|
安全 Java 容器
告别繁琐判空:Optional让你的Java代码更优雅
告别繁琐判空:Optional让你的Java代码更优雅
|
5月前
|
安全 Java 容器
告别空指针噩梦:Optional让Java代码更优雅
告别空指针噩梦:Optional让Java代码更优雅
459 94
|
6月前
|
安全 Java 数据建模
Java记录类:简化数据载体的新选择
Java记录类:简化数据载体的新选择
341 101
|
6月前
|
安全 Java 开发者
Java记录类:简化数据载体的新方式
Java记录类:简化数据载体的新方式
334 100
|
7月前
|
安全 IDE Java
Java记录类型(Record):简化数据载体类
Java记录类型(Record):简化数据载体类
553 143
|
5月前
|
安全 Java 开发者
告别NullPointerException:掌握Java Optional的精髓
告别NullPointerException:掌握Java Optional的精髓
|
5月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
219 4
|
5月前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
284 5
|
5月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
365 5