Optional

作者: 一只有思想的小蚂蚁 | 来源:发表于2021-07-15 23:01 被阅读0次

一、Optional介绍
Optional是一个容器对象,它可能包含也可能不包含非null值。如果值存在,isPresent方法返回true;如果值不存在,这个对象被认为空并且isPresent方法返回false。
还提供了依赖于包含值是否存在的其他方法,例如orElse(Object)如果值不存在返回一个默认的值,ifPresent(Consumer)如果值存在执行相关操作。
主要用于作为需要表示“无结果”的,使用null会导致错误的方法返回类型。一个Optional类型的变量本身不应该为null;它应该始终指向一个Optional实例。
下面是对Optional的方法进行解释:
二、Optional的构造方法
Optional的构造方法有以下两个:

private Optional() {
        this.value = null;
    }
//构造一个空实例

private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
//根据value构造一个实例,如果value值为null,抛NullPointerException

全部用private修饰,使用的是单例模式
三、Optional的静态方法
Optional的静态方法有三个,可以用来生成Optional实例:

public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

返回一个空Optional实例,对于这个Optional实例没有值存在。
尽管这样做很诱人,但要避免测试对象为空用"=="来与Optional.empty()返回的实例进行比较,这样不能保证它是一个单例。相反,要使用isPresent()方法。

public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

返回一个值不等于Null的Optional实例,如果值为Null,抛出空指针异常

public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

如果值不等于Null,根据给定的值返回Optional,如果为值null,返回一个空Optional
四、Optional实例方法:

public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
//如果值存在,返回。值不存在抛NoSuchElementException。 首选方案是使用orElseThrow()方法。
public boolean isPresent() {
        return value != null;
    }
//如果有值,则返回true,否则返回false

public void ifPresent(Consumer<? super T> action) {
        if (value != null) {
            action.accept(value);
        }
    }:
//如果有一个值,就用这个值执行给定的操作,否则什么也不做。给定的操作如果为空抛空指针异常

public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
        if (value != null) {
            action.accept(value);
        } else {
            emptyAction.run();
        }
    }

//如果值存在,对值执行指定的操作。否则执行一个而基于空的操作。如果一个值出现并且给定的动作是null,或者没有值,并且给定的是基于空的操作是null。抛空指针异常。
public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent()) {
            return this;
        } else {
            return predicate.test(value) ? this : empty();
        }
    }
//如果存在一个值,且该值与给定的谓词匹配,则返回描述该值的Optional,否则返回空的Optional。filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.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));
        }
    }
//如果当前 Optional 为 Optional.empty,则依旧返回 Optional.empty;否则返回一个新的 Optional,该 Optional 包含的是:函数 mapper 在以 value 作为输入时的输出值。还可以多次调用map函数,以链式编程的形式

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);
        }
    }
//flatMap 方法与 map 方法的区别在于,map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用 Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional

//此方法类似于map(Function),但提供的映射器的结果已经是一个Optional,如果调用了flatMap,它不会用一个额外的Optional封装它。
示例:
Optional<String> username = Optional
        .ofNullable(getUserById(id))
        .map(user -> user.getUsername()); 
System.out.println("Username is: " + username.orElse("Unknown"));

可以多次使用map操作:
Optional<String> username = Optional
        .ofNullable(getUserById(id))
        .map(user -> user.getUsername())
        .map(name -> name.toLowerCase())
        .map(name -> name.replace('_', ' '));
        
System.out.println("Username is: " + username.orElse("Unknown"));

Optional<String> username = Optional
        .ofNullable(getUserById(id))
        .flatMap(user -> Optional.of(user.getUsername()))
        .flatMap(name -> Optional.of(name.toLowerCase()));
        
System.out.println("Username is: " + username.orElse("Unknown"));

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);
        }
    }
//如果一个 Optional 包含值,则返回自己;否则返回由参数 supplier 获得的 Optional

public T orElse(T other) {
        return value != null ? value : other;
    }
//如果 Optional 中有值则将其返回,否则返回 orElse 方法传入的参数


public T orElseGet(Supplier<? extends T> supplier) {
        return value != null ? value : supplier.get();
    }
//当 Optional 中有值的时候,返回值;当 Optional 中没有值的时候,返回从该 Supplier 获得的值


public T orElseThrow() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
//当 Optional 中有值的时候,返回值;没有值的时候会抛出NoSuchElementException异常,


public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }
//当 Optional 中有值的时候,返回值;没有值的时候会抛出NoSuchElementException异常,抛出的异常由传入的 exceptionSupplier 提供
public Stream<T> stream() {
        if (!isPresent()) {
            return Stream.empty();
        } else {
            return Stream.of(value);
        }
    }
//stream 方法的作用就是将 Optional 转为一个 Stream,如果该 Optional 中包含值,那么就返回包含这个值的 Stream;否则返回一个空的 Stream(Stream.empty())

相关文章

网友评论

      本文标题:Optional

      本文链接:https://www.haomeiwen.com/subject/dvrerltx.html