在 Java 8 中,引入了 Optional class 给我们在处理无法返回任何值的情况下,有了第三种选择。
Optional 概览,基于 Java 1
他是一个 final 类, 方法列表如下
name | 返回值 | 简述 |
---|---|---|
empty() | Optional |
返回一个空的实例 |
filter(Predicate<? super T> predicate) | Optional |
过滤 |
flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) | Optional | 扁平化操作 |
get() | T | 取值 |
ifPresent(Consumer<? super T> action) | void | 如果值存在,执行给定的操作 |
ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) | void | 如果存在,执行给定操作,否则运行 empty-base action |
isEmpty() | boolean | 是否为空 |
isPresent() | boolean | 是否有值 |
map(Function<? super T, ? extends U> mapper) | Optional | 对每个元素操作 |
of(T value) | Optional |
生成对象 |
ofNullable(T value) | Optional |
生成 empty 或 有值的 optional 对象 |
or(Supplier<? extends Optional<? extends T>> supplier) | Optional |
present 返回自己,否则返回 supplier 生成的对象 |
orElse(T other) | T | present 返回自己,否则返回 else 中指定的值 |
orElseGet(Supplier<? extends T> supplier) | T | present 返回自己,否则返回 else 中指定的 spplier 生成的对象 |
orElseThrow() | T | 存在值,返回,否则抛 NoSuchElementException |
stream() | Stream |
产生流 |
toString() | String | / |
1 | Optional<String> op = Optional.of("test"); |
or vs orElseGet: 返回值不同,前者返回 Optional 对象,后者返回的泛型指定的值
item 55
本节要点:
- Optional 强制客户端对返回值做校验
- 如果不能从 Optional 中 get 值,会抛 NoSuchElementException
- 永远不要通过返回 Optional 的方法返回 null, 这违背了设计的本意
- Optional 本质上与受检测异常相似
- 容器类,比如 map, stream, 数组和 optional 都不应该装载在 optional 中,你可以返回空的容器,比如空的数组
- 不要返回基本包装类型的 Option, 有其他的替代品比如 OptionalInt
- Optional 不要作为map, set 中的键元素,数组也不行
- Optional 相对而言还是比较消耗资源的,性能要求高的场景谨慎使用
示例代码:
1 | public static <E extends Comparable<E>> E max(Collection<E> c) { |
使用 Optional 优化
1 | public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) { |
使用 Stream 优化
1 | public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) { |
其他示例
1 | // 如果没有返回备选 |