Java Optional 的 orElse() 和 orElseGet() 的区别
1. 接收的参数不同
orElse()
方法以一个自定义类型的数据作为参数
public T orElse(T t)
orElseGet()
方法以一个Supplier
类型的数据作为参数
public T orElseGet(Supplier<? extends T> other)
2. 程序的执行过程不同
以下面一段代码为例:
public static void main(String[] args) {
String[] names = new String[]{"zhang", "wang", "li", "zhao", "wu"};
Optional.of("wang").orElse(getRandomName(names)); // 执行该句时会打印"Generating a name..."
Optional.of("wang").orElseGet(() -> getRandomName(names));
}
public static String getRandomName(String[] names) {
System.out.println("Generating a name...");
Random random = new Random();
return names[random.nextInt(5)];
}
在上述代码在运行Optional.of("wang").orElse(getRandomName(names))
时会打印"Generating a name...",而在运行Optional.of("wang").orElseGet(() -> getRandomName(names))
时没有任何输出,这说明了orElse()
中的函数getRandomName
被调用了,而orElseGet()
中的Lambda表达式没有执行。
产生上述现象的原因是,无论Optional对象中的值是否为空,orElse()
函数都会执行;而由于orElseGet()
中的参数为一个Supplier
方法,该方法的特点是仅在必要的时候执行,因此只有在Optional对象中的值为空时,orElseGet()
中的Supplier
方法才会执行。
3. 性能差异
由于orElse()
和orElseGet()
执行过程的差异,orElseGet()
方法的执行效率相对而言也更快,这是因为他会跳过不必要的方法调用。
因此,只有当默认值已经事先定义的情况下,才使用orElse()
,否则使用orElseGet()
更好。