- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.test.context.junit4.SpringRunner;
- import java.util.*;
- import java.util.function.Function;
- import java.util.function.Supplier;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- /**
- * @author 陈杨
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class OptionalTest {
- @Test
- public void testOptional() {
一, Optional 出现的缘由
/*
* A container object which may or may not contain a non-{@code null} value.
*
* 一个装泛型为 T 的 值容器 可以包含 Null 以规避 空指针异常
* public final class Optional<T>
*/
二, 深入理解 Value-based Classes
/*
* Value-based Classes
*
* https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html
*
* final immutable (但里面可以包含指向 可变对象的引用)
* 具有 equals,hashCode 和 toString 的实现 仅从实例的状态计算 而不是从其标识或任何其他对象或变量的状态计算
* 不使用身份敏感的操作, 例如实例之间的引用相等 (==) 实例的 hashCode, 或实例的内部锁(intrinsic lock) 同步
* 判断是否相等 仅比较 equals()方法 而非对象的引用(==)
* 没有可访问的构造函数 通过工厂方法实例化, 不保证实例创建的一致性(不一定是单例)
*
* 基于值的对象 没有 public 的构造方法 比较值是否相等(不比较引用)
*/
三, Optional 容器的构造
- // private static final Optional<?> EMPTY = new Optional<>();
- // private final T value;
- // Constructs an empty instance.
- // private Optional() { this.value = null; }
- /*
- * Constructs an instance with the described value.
- *
- * private Optional(T value) { this.value = Objects.requireNonNull(value); }
- */
- /*
- * Returns an empty {@code Optional} instance. No value is present for this {@code Optional}.
- *
- * public static<T> Optional<T> empty() {
- * @SuppressWarnings("unchecked")
- * Optional<T> t = (Optional<T>) EMPTY;
- * return t;
- * }
- */
- Optional<List<String>> empty = Optional.empty();
- /* 构造一个容器里不为 null 的容器对象
- *
- * public static <T> Optional<T> of(T value) { return new Optional<>(value); }
- */
- Optional<List<String>> optional = Optional.of(Arrays.asList("Kirito", "Love", "Asuna"));
- /* 构造一个容器里可能为 null 的容器对象
- *
- * public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); }
- */
四, 普通方法
- /* 获取容器中的所有值
- * public T get() {
- * if (value == null) {
- * throw new NoSuchElementException("No value present");
- * }
- * return value;
- * }
- */
- System.out.println("---------------------------------------\n");
- System.out.println("optional 容器中存在的值:" + optional.get());
- // 判断 容器中存在值 返回 true
- // public boolean isPresent() { return value != null; }
- System.out.println("---------------------------------------\n");
- System.out.println("optional 容器中存在值:" + optional.isPresent());
- System.out.println("empty 容器中存在值:" + empty.isPresent());
- // 判断 容器中不存在值 返回 true
- // @since 11
- // public boolean isEmpty() { return value == null; }
- System.out.println("---------------------------------------\n");
- System.out.println("optional 容器中不存在值:" + optional.isEmpty());
- System.out.println("empty 容器中不存在值:" + empty.isEmpty());
五, 高级拓展
- 1,ifPresent(Consumer)
- /*
- * 如果存在 value 对 value 进行一个 Consumer 消费
- * public void ifPresent(Consumer<? super T> action) {
- * if (value != null) {
- * action.accept(value);
- * }
- * }
- *
- */
- System.out.println("---------------------------------------\n");
- System.out.println("optional 容器中存在值就进行 Consumer 消费(打印输出)");
- optional.ifPresent(System.out::println);
- 2,ifPresentOrElse(Consumer)
- /* 如果存在 value 对 value 进行一个 Consumer 消费 不存在 执行 emptyAction(empty-based action)
- * @since 9
- * public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
- * if (value != null) {
- * action.accept(value);
- * } else {
- * emptyAction.run();
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- System.out.println("容器中存在值就打印值, 不存在打印 hello world");
- optional.ifPresentOrElse(System.out::println, () -> System.out.println("hello world"));
- empty.ifPresentOrElse(System.out::println, () -> System.out.println("hello world"));
- 3,filter(Predicate)
- /*
- * 如果存在 value 且符合预期 predicate 则对 value 进行预期操作 predicate.test(value) 否则返回 empty
- * public Optional<T> filter(Predicate<? super T> predicate) {
- * Objects.requireNonNull(predicate);
- * if (!isPresent()) {
- * return this;
- * } else {
- * return predicate.test(value) ? this : empty();
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- System.out.println("遍历集合元素");
- optional.filter(strings -> {
- strings.forEach(System.out::println);
- return true;
- });
- 4,or(Supplier)
- /*
- * 如果存在 value 则返回 value 否则使用 supplier 接口的 get()方法 构造出一个 Optional
- * @since 9
- * public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
- * Objects.requireNonNull(supplier);
- * if (isPresent()) {
- * return this;
- * } else {
- * @SuppressWarnings("unchecked")
- * Optional<T> r = (Optional<T>) supplier.get();
- * return Objects.requireNonNull(r);
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- Supplier<Optional<List<String>>> sup =
- () -> Optional.ofNullable(Arrays.asList("Optional", "or", "supplier"));
- System.out.println(empty.or(sup));
- 5,Stream.of(value)
- /*
- * 如果存在 value 则返回 Stream.of(value) 否则返回一个 Stream.empty()
- * @since 9
- * public Stream<T> stream() {
- * if (!isPresent()) {
- * return Stream.empty();
- * } else {
- * return Stream.of(value);
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- System.out.println("以 stream 流 遍历 optional 容器内的值");
- Stream<List<String>> stream = Stream.of(optional.get());
- stream.forEach(System.out::println);
- 6,orElse(T other)
- /*
- * 如果存在 value 则返回 value 否则返回 T other
- * public T orElse(T other) {
- * return value != null ? value : other;
- * }
- */
- System.out.println("---------------------------------------\n");
- System.out.println("容器中存在值就返回值 不存在就返回{\"hello\",\"world\"}");
- System.out.println(empty.orElse(Arrays.asList("hello", "world")));
- 7,orElseGet(Supplier)
- /*
- * 如果存在 value 则返回 value 否则返回 Supplier 接口实现
- * public T orElseGet(Supplier<? extends T> supplier) {
- * return value != null ? value : supplier.get();
- * }
- */
- System.out.println("---------------------------------------\n");
- Supplier<List<String>> listSupplier = () -> Arrays.asList("do", "orElseGet");
- System.out.println(empty.orElseGet(listSupplier));
- 8,orElseThrow
- /*
- * 如果存在 value 则返回 value 否则抛出异常 NoSuchElementException
- * @since 10
- * public T orElseThrow() {
- * if (value == null) {
- * throw new NoSuchElementException("No value present");
- * }
- * return value;
- * }
- */
- System.out.println("---------------------------------------\n");
- System.out.println("容器中存在值就返回值 不存在就返回 NoSuchElementException");
- System.out.println(optional.orElseThrow());
- try {
- System.out.println(empty.orElseThrow());
- } catch (NoSuchElementException e) {
- System.out.println("NoSuchElementException ---> No value present");
- }
- 9,orElseThrow(Supplier)
- /*
- * 如果存在 value 则返回 value 否则使用 Supplier 接口生成一个被抛出的 exceptionSupplier -->exception
- * public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
- * if (value != null) {
- * return value;
- * } else {
- * throw exceptionSupplier.get();
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- Supplier<NoSuchElementException> noSuchElementException = NoSuchElementException::new;
- try {
- System.out.println(empty.orElseThrow(noSuchElementException));
- } catch (NoSuchElementException e) {
- System.out.println("Supplier NoSuchElementException ---> No value present");
- }
- 10,map(Function)
- /*
- *
- * 如果存在 value 则返回 value 并作为 mapper 的输入 将其输出作为新的 value 存放至 Optional 否则返回一个 null 的 Optional
- * 如果经过 mapper 后得到的结果为 null 返回一个 null 的 Optional
- * mapper 函数若为 null 则抛出 NullPointerException
- * 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));
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- Function<List<String>, List<String>> function =
- up -> up.stream().map(String::toUpperCase).collect(Collectors.toList());
- Optional<List<String>> o = optional.map(function);
- System.out.println(o.get());
- 11,flatMap(Function)
- /*
- * 如果存在 value 则返回 value 并作为 mapper 的输入 将其输出作为新的 value 存放至 Optional 否则返回一个 null 的 Optional
- * 如果经过 mapper 后得到的结果为 null 返回一个 null 的 Optional
- * mapper 函数若为 null 则抛出 NullPointerException
- *
- * 与 map 的方法的区别:
- * map
- *
- * return Optional.ofNullable(mapper.apply(value));
- *
- * flatMap
- *
- * Optional<U> r = (Optional<U>) mapper.apply(value);
- * return Objects.requireNonNull(r);
- * flatMap: 对集合中每个元素进行操作然后再扁平化
- *
- *
- * 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);
- * }
- * }
- */
- System.out.println("---------------------------------------\n");
- Function<List<String>, Optional<List<String>>> func =
- up -> Optional.of(up.stream().map(String::toUpperCase).collect(Collectors.toList()));
- Optional<List<String>> u = optional.flatMap(func);
- System.out.println(u.get());
- }
- }
六, 测试
- . ____ _ __ _ _
- /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ ( ( )\___ |'_ | '_| |'_ \/ _` | \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\__, | // //
- =========|_|==============|___/=/_/_/_/
- :: Spring Boot :: (v2.1.2.RELEASE)
- 2019-02-01 18:29:34.870 INFO 17140 --- [ main] com.java.design.java8.OptionalTest : Starting OptionalTest on DESKTOP-87RMBG4 with PID 17140 (started by 46250 in E:\IdeaProjects\design)
- 2019-02-01 18:29:34.871 INFO 17140 --- [ main] com.java.design.java8.OptionalTest : No active profile set, falling back to default profiles: default
- 2019-02-01 18:29:35.437 INFO 17140 --- [ main] com.java.design.java8.OptionalTest : Started OptionalTest in 0.775 seconds (JVM running for 1.574)
- ---------------------------------------
optional 容器中存在的值:[Kirito, Love, Asuna]
---------------------------------------
optional 容器中存在值: true
empty 容器中存在值: false
---------------------------------------
optional 容器中不存在值: false
empty 容器中不存在值: true
---------------------------------------
optional 容器中存在值就进行 Consumer 消费(打印输出)
- [Kirito, Love, Asuna]
- ---------------------------------------
容器中存在值就打印值, 不存在打印 hello world
- [Kirito, Love, Asuna]
- hello world
- ---------------------------------------
遍历集合元素
- Kirito
- Love
- Asuna
- ---------------------------------------
- Optional[[Optional, or, supplier]]
- ---------------------------------------
以 stream 流 遍历 optional 容器内的值
- [Kirito, Love, Asuna]
- ---------------------------------------
容器中存在值就返回值 不存在就返回{"hello","world"}
- [hello, world]
- ---------------------------------------
- [do, orElseGet]
- ---------------------------------------
容器中存在值就返回值 不存在就返回 NoSuchElementException
- [Kirito, Love, Asuna]
- NoSuchElementException ---> No value present
- ---------------------------------------
- Supplier NoSuchElementException ---> No value present
- ---------------------------------------
- [KIRITO, LOVE, ASUNA]
- ---------------------------------------
- [KIRITO, LOVE, ASUNA]
- Process finished with exit code 0
深入理解 lambda 表达式 与 Optional Null 源码解析(Java11 三)
来源: http://www.bubuko.com/infodetail-2941919.html