Optional源码分析和使用
来源:互联网 发布:js怎么传值给jsp 编辑:程序博客网 时间:2024/06/05 03:41
平时在写代码的时候总要做很多非空的判断,Jdk8提供了一个类Optional可以更优雅的使用非空判断,它的源码并不是特别的多,我们可以线来分析下源码:
public final class Optional<T> { // 构造值为null的Optional private static final Optional<?> EMPTY = new Optional<>(); // 当前Optional的值 private final T value; // 私有构造方法 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); } // 获取非空的值 public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } // 非空判断 public boolean isPresent() { return value != null; } // 如果非空,回调函数 public void ifPresent(Consumer<? super T> consumer) { if (value != null) consumer.accept(value); } // 过滤是否符合要求的值 public Optional<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); if (!isPresent()) return this; else return predicate.test(value) ? this : empty(); } // 通过传入的参数处理获得想要的值 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)); } } // 通过传入的参数处理获得想要的值,并且这个值非空 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)); } } // 如果Optional的值为null,则返回这个对象 public T orElse(T other) { return value != null ? value : other; } // 可以用函数去构造这个orElse返回的对象 public T orElseGet(Supplier<? extends T> other) { return value != null ? value : other.get(); } // 如果为空就抛出指定的异常 public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { if (value != null) { return value; } else { throw exceptionSupplier.get(); } } // 逻辑等于 @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Optional)) { return false; } Optional<?> other = (Optional<?>) obj; return Objects.equals(value, other.value); } // 与equals一样重写 @Override public int hashCode() { return Objects.hashCode(value); } @Override public String toString() { return value != null ? String.format("Optional[%s]", value) : "Optional.empty"; }}
接下来是测试部分:
定义好两个类:
public static class Person { private String name; private Car car; public Person() { } public Person(String name) { this.name = name; } // getter setter } public static class Car { private String name; // getter setter }
测试代码
Optional<Person> personOptional = Optional.of(new Person("micro")); // 另一个对象 Person person = new Person(); person.setName("micro2"); System.out.println(personOptional.orElse(person).getName()); // 打印 micro // 构造一个value为null的person personOptional = Optional.empty(); // personOptional value is null,so print person's name micro2 System.out.println(personOptional.orElse(person).getName()); // 打印 micro2 // orElseGet can contruct this person System.out.println(personOptional.orElseGet(() -> { return new Person("micro3"); }).getName()); // 打印micro3 System.out.println(personOptional.isPresent()); // 等价value != null false personOptional = Optional.of(new Person("micro4")); System.out.println(personOptional.isPresent()); // true try { personOptional = Optional.of(null); } catch (Exception e) { // 会执行 e.printStackTrace(); System.out.println("of"); } try { personOptional = Optional.ofNullable(null); } catch (Exception e) { // 不会执行 e.printStackTrace(); System.out.println("ofNullable"); } System.out.println(" ----- filter ----"); personOptional = Optional.of(new Person("micro5")); personOptional = personOptional.filter((filterPerson) -> { return filterPerson.getName().equals("micro6"); // 会被过滤 }); System.out.println(personOptional.isPresent()); // false // 重置 personOptional = Optional.of(new Person("micro5")); personOptional = personOptional.filter((filterPerson) -> { return filterPerson.getName().equals("micro5"); // 不会被过滤 }); System.out.println(personOptional.isPresent()); // true System.out.println("------ map --------"); // map : 消灭连续的if personOptional = Optional.of(new Person("micro7")); System.out.println(personOptional.map((p) -> { return p.getCar(); // 返回car }).map((car) -> { return car.getName(); // 返回名字 }).orElseGet(() -> { // 如果中间有空, 返回这个默认值 return "default car name"; }));
阅读全文
0 0
- Optional源码分析和使用
- [Guava源码日报](5)Optional分析
- ThreadLocal使用和源码分析
- greendao3 使用和源码分析
- NumberUtils源码分析和使用
- jedis源码分析和使用
- WinCE EBOOT中的Optional函数和BootPart分析
- Spring源码分析【6】-ThreadLocal的使用和源码分析
- Okhttp使用和源码分析三(OkHttp源码分析)
- Android_EventBus的使用和源码分析
- Android IntentService的使用和源码分析
- Otto的使用和源码分析
- Shiro使用和源码分析---1
- Shiro使用和源码分析---3
- Shiro使用和源码分析---4
- Shiro使用和源码分析---5
- Shiro使用和源码分析---6
- Shiro使用和源码分析---7
- JSP小整理(一)
- 判断输入的二叉树是否是一致
- 并行执行(Callable和Future)一定比串行执行效率高吗?
- newFixedThreadPool线程池数量问题
- 临时用来存放图片的博客
- Optional源码分析和使用
- GKPolygonObstacle
- Linux基础学习笔记
- 简单选择排序
- css常用文本属性
- 死锁是怎样形成的
- BZOJ 1597 浅谈构造斜率--优化动态规划转移
- 基于kinect的人体动作识别系统(算法和代码都放出)
- 使用refind引导多系统