返回

`Optional.orElse()` 与 `Optional.orElseGet()` 有何区别?何时使用?

java

Optional.orElse()Optional.orElseGet() 的对比

引言

在 Java 中,Optional 类提供了处理空值的有力工具。其两个方法,orElse()orElseGet(), 旨在返回非空值。然而,它们在某些情况下表现出不同的行为。本文将深入探讨这两个方法之间的差异,并提供如何有效利用它们的见解。

orElse()

orElse() 方法接受一个值作为参数,如果 Optional 存在值,则返回该值,否则返回提供的值。换句话说,它提供了一个默认值,如果 Optional 为空,则返回该值。

orElseGet()

另一方面,orElseGet() 方法接受一个 Supplier<T> 函数作为参数,该函数不接受任何参数并返回 T 类型的对象。如果 Optional 存在值,则返回该值,否则调用提供的函数并返回其返回值。

何时使用 orElseGet()

使用 orElseGet() 的主要原因是可以推迟对默认值计算的执行。这意味着你可以创建只在你需要时才执行的复杂计算或查找。

延迟执行的优势

例如,假设你有一个 User 类的 Optional 实例,并且你希望获取该用户的姓名。如果你使用 orElse(),则即使 Optional 为空,你也需要计算默认名称。然而,如果你使用 orElseGet(),则只有当 Optional 为空时,你才会执行计算。

Optional<User> userOptional = ...;

String name = userOptional.orElse("Unknown"); // 计算默认名称,即使 Optional 为空
String name = userOptional.orElseGet(() -> getUserFromDB()); // 只有当 Optional 为空时才从数据库获取用户

使用 Supplier

使用 Supplier 函数的一个好处是,你可以利用它来创建更通用的代码。例如,如果你希望在 orElse()orElseGet() 中使用相同的默认值,你可以将该值存储在一个 Supplier 中,然后在需要时使用它。

Supplier<String> defaultNameSupplier = () -> "Unknown";

String name = userOptional.orElse(defaultNameSupplier.get()); // 使用 Supplier 提供的默认名称
String name = userOptional.orElseGet(defaultNameSupplier); // 使用 Supplier 提供的默认名称

其他差异

除了延迟执行之外,orElse()orElseGet() 之间没有其他主要差异。它们都返回相同类型的对象,并且在 Optional 为空时抛出相同的异常。

结论

orElse()orElseGet() 都是处理空值的有效方法。orElse() 提供了一个简单的默认值,而 orElseGet() 允许你延迟计算,只有在你真正需要时才执行。根据你具体的需求选择合适的方法至关重要。

常见问题解答

1. 我应该总是使用 orElseGet() 吗?

不,如果你的默认值可以简单地计算,则使用 orElse() 就足够了。

2. 我可以使用 lambda 表达式代替 Supplier 函数吗?

是的,lambda 表达式可以作为 orElseGet() 方法中 Supplier 函数的替代品。

3. 我可以在 orElseGet() 方法中抛出异常吗?

是的,你可以在 orElseGet() 方法中抛出异常,但确保异常类型与 Optional 中的值类型兼容。

4. orElse()orElseGet() 方法哪个更快?

orElse() 通常比 orElseGet() 更快,因为不需要调用 Supplier 函数。

5. 我可以在 orElse() 方法中使用 null 值吗?

否,不能在 orElse() 方法中使用 null 值作为默认值,因为 Optional 旨在处理非空值。