Optional类中orElse和orElseGet方法

今天在开发中使用Optional类避免NPE时遇到一个问题。

使用Optional集合调用isPresent()方法判断集合中是否有值存在,有返回其中的值,否则返回null

1
2
3
4
5
6
7
public Person getPersonById(String id){
Optional<Person> optional = personRepository.findById(id);
if (optional.isPresent()){
return optional.get();
}
return null;
}

问题来了,这时Idea出现黄色警告:Can be replaced with single expression in functional style. 可以被函数式表达式替换,于是我用idea自动修正,代码变成了:

1
2
3
4
public Person getPersonById(String id){
Optional<Person> optional = personRepository.findById(id);
return optional.orElse(null);
}

打开Optional类源代码,原来orElse方法就是一个三元运算符,如果value不为空返回value,如果为空返回other

1
2
3
4
5
6
7
8
9
10
/**
* 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;
}

又上网查阅了一下资料,Optional类中还有一个类似的方法orElseGet,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 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();
}

StackOverFlow中解释两个方法区别的例子:

X : buyNewExpensivePhone() called

Optional.isPresent() true false
findMyPhone(int phoneId).orElse(buyNewExpensivePhone()) X X
findMyPhone(int phoneId).orElseGet(() -> buyNewExpensivePhone()) X

结论:optional.isPresent() == false时,orElse()和orElseGet()没有区别;而当optional.isPresent() == true时,无论你是否需要,orElse始终会调用后续函数

问题地址:https://stackoverflow.com/questions/33170109/difference-between-optional-orelse-and-optional-orelseget#

0%