Lambda从入门到精通之二十五 Optional多种方法读取内部值的方法

Optional提供了多种方法可以从Optional类型中读取值的方法,我们来看一下方法和对应的源码。
1、get()是这些方法中最简单的方法,直接获取Optional中的值,但又最不安全的方法。如果变量存在,它直接返回变量值,否则就抛出一个NoSuchElementException异常。这个方法不建议使用,除非你确定其中一定包含变量值。
看源码:

/**
 * If a value is present in this {@code Optional}, returns the value,
 * otherwise throws {@code NoSuchElementException}.
 *
 * @return the non-null value held by this {@code Optional}
 * @throws NoSuchElementException if there is no value present
 *
 * @see Optional#isPresent()
 */
public T get() {
	if (value == null) {
		throw new NoSuchElementException("No value present");
	}
	return value;
}

2、orElse(T other),当Optional对象不包含值时提供一个默认值,这个方法其实相当于一个三目运算符,例如:address !=null ? address:new Addrsss()
看源码:

/**
 * Return the value if present, otherwise return {@code other}.
 *
 * @param other the value to be returned if there is no value present, may
 * be null
 * @return the value, if present, otherwise {@code other}
 */
public T orElse(T other) {
	return value != null ? value : other;
}
	

3、orElseGet(Supplier other),是orElse方法的延迟调用版,或者说是性能提升版,如果Optional中的值为空,才调用这个方法,那么这个逻辑的作用是什么?如果是为空时创建的替补对象非常复杂时,可以用这个方法,程序就不需要浪费资源去创建可能不用的对象了(如果Optional中的值不为空,就不会创建替补对象)。
看源码:

/**
 * Return the value if present, otherwise invoke {@code other} and return
 * the result of that invocation.
 *
 * @param other a {@code Supplier} whose result is returned if no value
 * is present
 * @return the value if present otherwise the result of {@code other.get()}
 * @throws NullPointerException if value is not present and {@code other} is
 * null
 */
public T orElseGet(Supplier<? extends T> other) {
	return value != null ? value : other.get();
}

从源码可以看出orElseGet方法的参数本身就是一个lambda表达式,只有执行到自己的分支,才执行这个方法,也就是other.get()才开始执行,这就实现了延时创建的效果。

4、orElseThrow(Supplier exceptionSupplier)和get方法非常类似,Optional对象为空时都会抛出一个异常,但是使用orElseThrow抛出自定义的异常类型。
看源码:

/**
 * Return the contained value, if present, otherwise throw an exception
 * to be created by the provided supplier.
 *
 * @apiNote A method reference to the exception constructor with an empty
 * argument list can be used as the supplier. For example,
 * {@code IllegalStateException::new}
 *
 * @param <X> Type of the exception to be thrown
 * @param exceptionSupplier The supplier which will return the exception to
 * be thrown
 * @return the present value
 * @throws X if there is no value present
 * @throws NullPointerException if no value is present and
 * {@code exceptionSupplier} is null
 */
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
	if (value != null) {
		return value;
	} else {
		throw exceptionSupplier.get();
	}
}

5、ifPresent(Consumer)作用是判断Optonal中的值是否为空,存在值返回true,否则false。
看源码:

/**
 * Return {@code true} if there is a value present, otherwise {@code false}.
 *
 * @return {@code true} if there is a value present, otherwise {@code false}
 */
public boolean isPresent() {
	return value != null;
}