聆听 沉淀 传播 … 关注微信公众号【
Java之言
】,助你放弃编程之路!java
系列文章目录
序号 | 标题 | 文章连接 |
---|---|---|
1 | 玩转 Java8 Stream,让你代码更高效紧凑简洁 | https://blog.csdn.net/chenlixiao007/article/details/112752413 |
文章目录
- 系列文章目录
- 1、Optional 是什么?
- 2、Optional 有什么用?
- 3、Optional 源码详解
- 4、Optional 类的使用
-
- 4.1 Optional 对象建立
- 4.2 get()
- 4.3 isPresent()
- 4.4 ifPresent(Consumer<? super T> consumer)
- 4.5 filter(Predicate<? super T> predicate)
- 4.6 map(Function<? super T, ? extends U> mapper)
- 4.7 orElse(T other)
- 4.7 orElseGet(Supplier<? extends T> other)
- 4.8 orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
- 4.9 与 Stream 结合使用
1、Optional 是什么?
官方定义:
public final class Optional<T> extends Object
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).
This is a value-based class; use of identity-sensitivemin operations (including reference equality (==), identity hash code, or synchronization) on instances of Optional may have unpredictable results and should be avoided.web
Optional
类,一个可包含或不包含非null值
的容器对象
。若是值存在,isPresent()
方法将返回 true 而且get()
返回该值。
这个类还提供了其余方法,这些方法取决于它所包含值的存在与否,例如orElse()
(若是不存在值,则返回默认值)和ifPresent()
(若是存在值,则执行代码块)。
这是一个基于值的类,因此对于Optional实例的一些身份敏感操做(包括引用相等==,hashCode,同步)会产生没法预料的结果,应该避免使用。编程
2、Optional 有什么用?
- 既然 Optional 类里面包含的值能够为
null
,不言而喻,那咱们就能够不用显式地进行空值检测,即咱们能够不用作判空操做,很好的解决了空指针异常问题(NullPointerException
)。- Java8引入了函数式编程,而 Optional 是其中必不可少的一部分,帮助在范式中实现。结合 Stream 能够写出简洁高效的代码。
先举个栗子,输出一个员工的岗位名称,若是岗位名称为空,则输出默认值 - 实习生:微信
if (null != staff.getPost().getName()) { System.out.println(staff.getPost().getName()); } else { System.out.println("实习生"); }
以上语句有可能抛出NPE,为了健壮性,咱们须要写判空:app
if (null != staff) { Post post = staff.getPost(); if (null != post) { String name = post.getName(); if (null != name) { System.out.println(name); } else { System.out.println("实习生"); } } }
可是写了大量的判空操做,很繁琐,代码冗余还很难维护。若是使用Optional则很简单以下:ide
System.out.println( Optional.ofNullable(staff).map(Staff::getPost).map(Post::getName).orElse("实习生"));
3、Optional 源码详解
public final class Optional<T> { // 包含一个空值的Optional容器对象 private static final Optional<?> EMPTY = new Optional<>(); // Optional容器包含的值 private final T value; // 私有构造方法,建立一个包含空值的Optional容器对象 private Optional() { this.value = null; } // 静态方法,建立一个空值的Optional容器对象 public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; } // 私有构造方法,建立一个包含非空值的Optional容器对象 private Optional(T value) { this.value = Objects.requireNonNull(value); } // 静态方法,建立一个包含非空值的Optional容器对象 public static <T> Optional<T> of(T value) { return new Optional<>(value); } // 静态方法,建立一个包含可空值的Optional容器对象 public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); } // 获取值,若是值为null,则抛出异常 public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } // 判断值是否不为null public boolean isPresent() { return value != null; } // 若是值不为null,则使用改值调用consumer函数 public void ifPresent(Consumer<? super T> consumer) { if (value != null) consumer.accept(value); } // 若是值存志,而且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,不然返回一个空的Optional。 public Optional<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); if (!isPresent()) return this; else return predicate.test(value) ? this : empty(); } // 若是值存在,则对其执行调用映射函数获得新的返回值。不然返回空Optional。 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)); } } // 若是值存在,返回基于Optional包含的映射方法的值,不然返回一个空的Optional public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); } } // 若是值存在,返回此值, 不然返回other。 public T orElse(T other) { return value != null ? value : other; } // 若是值存在,返回此值, 不然调用other函数,并返回other函数的结果。 public T orElseGet(Supplier<? extends T> other) { return value != null ? value : other.get(); } // 若是值存在,返回此值,不然抛出由Supplier继承的异常 public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { if (value != null) { return value; } else { throw exceptionSupplier.get(); } } }
4、Optional 类的使用
4.1 Optional 对象建立
// 建立一个空值的Optional对象 Optional<Object> emptyOptional = Optional.empty(); // 建立一个值可为空的Optional对象 Optional<Staff> staffOptional = Optional.ofNullable(staff); // 建立一个非空值的Optional对象 Optional<Staff> staffOptional1 = Optional.of(staff);
4.2 get()
// 返回Optional容器对象中包含的值,若是值为null则抛出异常 Staff staff = staffOptional.get();
4.3 isPresent()
// 判断值是否存在 if (staffOptional.isPresent()) { Staff staff = staffOptional.get(); }
4.4 ifPresent(Consumer<? super T> consumer)
// 若是值存在,则输出值 staffOptional.ifPresent(System.out::println);
4.5 filter(Predicate<? super T> predicate)
// 是否存在18岁的员工,若是存在,则输出她的姓名 staffOptional.filter(staff -> staff.getAge() == 18) .ifPresent(staff -> System.out.println(staff.getName()));
4.6 map(Function<? super T, ? extends U> mapper)
// 获取员工的姓名,若是staff或name为null,输出'未知' System.out.println(staffOptional.map(Staff::getName).orElse("未知"));
4.7 orElse(T other)
// 若是staff为null,将新生成的Staff对象赋值给staff staff = Optional.ofNullable(staff).orElse(new Staff());
4.7 orElseGet(Supplier<? extends T> other)
// // 若是staff为null,才new出一个Staff对象,赋值给staff,它与orElse不一样的是执行时机不一样,orElseGet是值为空才调用other函数。 staff = Optional.ofNullable(staff).orElseGet(Staff::new);
4.8 orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
// 若是staff为null,则抛出异常 staff = Optional.ofNullable(staff).orElseThrow(() -> new NullPointerException());
4.9 与 Stream 结合使用
// 找出一个员工大于等于18岁的员工 Optional<Staff> staffOptional = staffList.stream().filter(staff -> staff.getAge() >= 18).findFirst(); if (staffOptional.isPresent()) { Staff staff = staffOptional2.get(); }
本文同步分享在 博客“Μr.ηobοdy”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。svg