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() {
/* * A container object which may or may not contain a non-{@code null} value. * * 一个装泛型为T的 值容器 能够包含Null 以规避 空指针异常 * public final class Optional<T> */
/* * 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的构造方法 比较值是否相等(不比较引用) */
// 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());
一、ifPresent(Consumer)html
/* * 若是存在 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);
二、ifPresentOrElse(Consumer)java
/* 若是存在 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"));
三、filter(Predicate)spring
/* * 若是存在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; });
四、or(Supplier)api
/* * 若是存在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));
五、Stream.of(value)oracle
/* * 若是存在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);
六、orElse(T other)app
/* * 若是存在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")));
七、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));
八、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"); }
九、orElseThrow(Supplier)ui
/* * 若是存在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"); }
十、map(Function)this
/* * * 若是存在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());
十一、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