Java基础 - Java8 - Optional - 方法解析(附源码)

注:本文档为参照他人文档编写,并添加源码以及个人理解

of

null对象创建一个Optional对象,如果传入参数为null,将会抛出NullPointerException

//调用工厂方法创建Optional对象
Optional name = Optional.of("W_Cat&B_Hat");
//传入参数为null,抛出NullPointerException
Optional name = Optional.of(null);
// of() 源码
public static <T> Optional<T> of(T value) {
    return new Optional<>(value);
}

private Optional(T value) {
    this.value = Objects.requireNonNull(value);
}

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

ofNullable

为指定的值创建一个Optional对象,如果指定的值为null,则返回一个空Optional对象

Optional name = Optional.ofNullable("W_Cat&B_Hat");
Optional nullOpt = Optional.ofNullable(null);
// ofNullalbe() 源码
public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}

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

private static final Optional<?> EMPTY = new Optional<>();

isPresent

值存在返回true,不存在返回false

Optional name = Optional.of("W_Cat&B_Hat");
if (name.isPresent()) {
    System.out.println(name.get());
}
// isPresent() 源码
public boolean isPresent() {
    return value != null;
}

ifPresent

如果有值,则调用处理方法,否则不做处理
传入参数为Consumer容器,也支持直接传入lambda表达式

Optional name = Optional.of("W_Cat&B_Hat")
name.ifPresent((value) -> {
    System.out.println(value);
});
//ifPresent 源码
public void ifPresent(Consumer<? super T> consumer) {
    if (value != null)
        consumer.accept(value);
}

get

如果Optional对象有值则返回,否则抛出 NoSuchElementException

Optional name = Optional.of("W_Cat&B_Hat")
System.out.println(name.get());
//get() 源码
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

orElse orElseGet

如果有值则返回,否则返回指定值

区别:
orElse() 方法参数为普通对象,如下opt.orElse(getResult())传入的其实是getResult()方法的返回值,所以getResult()方法会先一步执行,故无论opt是否有值,getResult()都会执行,这一点需要注意

orElseGet() 方法参数为普通对象 ,但会封装到Supplier容器中,并支持lambda表达式,如下opt.orElseGet(() -> getResult())传入的封装了getResult()方法的lambda表达式,所以getResult()方法的执行与否依赖于opt是否有值

public class DemoTest {
    public static void main(String[] args) {

        Optional<Object> opt = Optional.ofNullable(null);

        Object orElseResult = opt.orElse(getResult());
        Object orElseGetResult = opt.orElseGet(() -> getResult());

        System.out.println(orElseResult.toString());
        System.out.println(orElseGetResult.toString());
    }

    public static int getResult() {
        System.out.println("getResult run");
        return 1;
    }
}
// orElse() 源码
public T orElse(T other) {
    return value != null ? value : other;
}

// orElseGet() 源码
public T orElseGet(Supplier<? extends T> other) {
    return value != null ? value : other.get();
}

orElseThrow

如果有值则返回,否则抛出异常
传入参数必须是继承Throwable的类,即异常类。

public class DemoTest {
    public static void main(String[] args) {
    
        Optional<Object> opt = Optional.ofNullable(null);
        
        try {
            opt.orElseThrow(UserDefinedException::new);
        } catch (UserDefinedException e) {
            e.printStackTrace();
        }
    }
}

public class UserDefinedException extends Throwable {
    UserDefinedException() {
        super();
    }
    UserDefinedException(String msg) {
        super(msg);
    }
    @Override
    public String getMessage() {
        return"No value present in the Optional instance";
    }
}

//运行结果
com.example.config.UserDefinedException: No value present in the Optional instance
	at java.util.Optional.orElseThrow(Optional.java:290)
	at com.example.config.DemoTest.main(DemoTest.java:17)
// orElseThrow() 源码
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

map flapMap

如果有值,则调用map()/flapMap()得到返回值;如果返回值为null,返回空Optional;否则返回包含返回值的Optional

区别:
由源码可知,map()方法不要求mapper.apply(value)的结果为Optional,会自行包装为Optional
flapMap()方法要求mapper.apply(value)的结果必须为Optional

Optional name = Optional.of("W_Cat&B_Hat")
Optional mapUpperName = name.map((value) -> value.toUpperCase());
Optional flapMapUpperName = name.flapMap((value -> Optional.of(value.toUpperCase())));
// 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));
    }
}

// flapMap() 源码
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));
    }
}

你可能感兴趣的:(Java基础)