Optional
类中的 map
和 flatMap
方法都用于处理 Optional
中的值,但它们的使用场景和行为有所不同。以下是它们的主要区别和使用场景:
map
方法
定义
public <U> Optional<U> map(Function<? super T, ? extends U> mapper)
- 功能:
map
方法将Optional
中的值应用于提供的Function
,然后返回一个包含函数结果的新的Optional
。如果原始Optional
是空的,则返回一个空的Optional
。 - 返回值:
map
方法返回一个Optional<U>
,其中U
是Function
处理后生成的结果类型。
示例
假设我们有以下类:
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
使用 map
方法将 Person
对象的 name
转换为 Optional<String>
:
Optional<Person> optionalPerson = Optional.of(new Person("Alice"));
Optional<String> optionalName = optionalPerson.map(Person::getName);
- 解释:
optionalPerson
中的Person
对象通过getName()
方法被转换成一个新的Optional<String>
对象。
flatMap
方法
定义
public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<U>> mapper)
- 功能:
flatMap
方法将Optional
中的值应用于提供的Function
,这个Function
生成一个新的Optional
。然后flatMap
将这些Optional
结果“平铺”成一个新的Optional
。如果原始Optional
是空的,则返回一个空的Optional
。 - 返回值:
flatMap
方法返回一个Optional<U>
,其中U
是Function
生成的Optional<U>
中的结果类型。
示例
假设我们有以下类:
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Optional<String> getOptionalName() {
return Optional.of(name);
}
}
使用 flatMap
方法将 Person
对象的 getOptionalName()
结果展平:
Optional<Person> optionalPerson = Optional.of(new Person("Alice"));
Optional<String> optionalName = optionalPerson.flatMap(Person::getOptionalName);
- 解释:
optionalPerson
中的Person
对象通过getOptionalName()
方法生成一个Optional<String>
。flatMap
会将这个嵌套的Optional
展平成一个Optional<String>
。
主要区别
Function
的返回类型:map
:map
方法的Function
返回一个普通类型(U
)。map
处理原始值并将结果包装在一个新的Optional
中。flatMap
:flatMap
方法的Function
返回一个Optional
类型(Optional<U>
)。flatMap
处理原始值并将结果展平,避免了嵌套的Optional
。
- 嵌套
Optional
:map
:不会展平Optional
,会产生一个嵌套的Optional
(即Optional<Optional<U>>
)。flatMap
:会展平嵌套的Optional
,最终结果是一个平铺的Optional<U>
。
什么时候使用
- 使用
map
:当你需要将Optional
中的值转换为另一种类型,但转换后的结果不需要包装在新的Optional
中时使用map
。 - 使用
flatMap
:当你需要将Optional
中的值转换为一个新的Optional
时使用flatMap
,特别是当转换后的结果已经是一个Optional
时,flatMap
可以帮助展平嵌套的Optional
。
例子对比
import java.util.Optional;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Optional<String> getOptionalName() {
return Optional.of(name);
}
}
public class Main {
public static void main(String[] args) {
Optional<Person> optionalPerson = Optional.of(new Person("Alice"));
// 使用 map
Optional<String> nameWithMap = optionalPerson.map(Person::getName);
System.out.println(nameWithMap); // 输出: Optional[Alice]
// 使用 flatMap
Optional<String> nameWithFlatMap = optionalPerson.flatMap(Person::getOptionalName);
System.out.println(nameWithFlatMap); // 输出: Optional[Alice]
}
}
map
产生了一个Optional<Optional<String>>
,虽然在这个例子中它直接产生了Optional<String>
,但通常map
不会自动展平嵌套的Optional
。flatMap
直接展平了嵌套的Optional
,返回了一个Optional<String>
,避免了嵌套的Optional
。