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