What's the difference between these two methods: Optional.flatMap() and Optional.map()?
这两种方法有什么区别:Optional.flatMap()和Optional.map()?
An example would be appreciated.
一个例子将不胜感激。
4 个解决方案
#1
84
Use map
if the function returns the object you need or flatMap
if the function returns an Optional
. For example:
如果函数返回您需要的对象,则使用map;如果函数返回Optional,则使用flatMap。例如:
public static void main(String[] args) {
Optional<String> s = Optional.of("input");
System.out.println(s.map(Test::getOutput));
System.out.println(s.flatMap(Test::getOutputOpt));
}
static Optional<String> getOutputOpt(String input) {
return input == null ? Optional.empty() : Optional.of("output for " + input);
}
static String getOutput(String input) {
return input == null ? null : "output for " + input;
}
Both print statements print the same thing.
两个打印语句都打印相同的内容。
#2
36
They both take a function from the type of the optional to something.
它们都从可选类型中获取函数。
Map applies the function "as is" on the optional you have:
Map在您拥有的可选项上应用“原样”功能:
if (optional.isEmpty()) return Optional.empty();
else return Optional.of(f(optional.get()));
What happens if your function is a function from T -> Optional<U>
? Your result is now an Optional<Optional<U>>
!
如果你的函数是来自T - > Optional 的函数,会发生什么?您的结果现在是可选 <可选 >!
That's what flatMap
is about: if your function already returns an Optional
, flatMap
is a bit smarter and doesn't double wrap it, returning Optional<U>
. It's the composition of two functional idioms: map
and flatten
.
这就是flatMap的意思:如果你的函数已经返回一个Optional,那么flatMap有点聪明并且没有双重包装,返回Optional 。它是两个功能成语的组成:map和flatten。
#3
4
Note:- below is the illustration of map and flatmap function, otherwise Optional is primarily designed to be used as a return type only.
注意: - 下面是map和flatmap函数的图示,否则Optional主要设计为仅用作返回类型。
As you already may know Optional is a kind of container which may or may not contain a single object, so it can be used wherever you anticipate a null value(You may never see NPE if use Optional properly). For example if you have a method which expects a person object which may be nullable you may want to write the method something like this:
您可能已经知道Optional是一种容器,可能包含也可能不包含单个对象,因此可以在预期空值的任何地方使用它(如果正确使用Optional,您可能永远不会看到NPE)。例如,如果你有一个方法需要一个可以为空的person对象,你可能想要写这样的方法:
void doSome(Optional<Person> person){
/*and here you want to retrieve some property phone out of person
you may write something like this:
*/
Optional<String> phone = person.map((p)->p.getPhone());
phone.ifPresent((ph)->dial(ph));
}
class Person{
private String phone;
//setter, getters
}
Here you have returned a String type which is automatically wrapped in an Optional type.
在这里,您返回了一个String类型,它自动包装在Optional类型中。
If person class looked like this, i.e. phone is also Optional
如果人员班级看起来像这样,即电话也是可选的
class Person{
private Optional<String> phone;
//setter,getter
}
In this case invoking map function will wrap the returned value in Optional and yield something like:
在这种情况下,调用map函数会将返回的值包装在Optional中,并产生如下内容:
Optional<Optional<String>>
//And you may want Optional<String> instead, here comes flatMap
void doSome(Optional<Person> person){
Optional<String> phone = person.flatMap((p)->p.getPhone());
phone.ifPresent((ph)->dial(ph));
}
PS; Never call get method (if you need to) on an Optional without checking it with isPresent() unless you can't live without NullPointerExceptions.
PS;永远不要在一个Optional上调用get方法(如果你需要)而不用isPresent()检查它,除非你不能没有NullPointerExceptions。
#4
1
While already being answered someone new to Java might have not grasped this. What helped me was a look at the source code of the two functions.
虽然已经有人回答了Java新手,但可能还没有抓住这一点。帮助我的是看两个函数的源代码。
Map - wraps the result in an Optional.
Map - 将结果包装在Optional中。
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value)); //<--- wraps in an optional
}
}
flatMap - returns the 'raw' object
flatMap - 返回'raw'对象
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value)); //<--- returns 'raw' object
}
}
#1
84
Use map
if the function returns the object you need or flatMap
if the function returns an Optional
. For example:
如果函数返回您需要的对象,则使用map;如果函数返回Optional,则使用flatMap。例如:
public static void main(String[] args) {
Optional<String> s = Optional.of("input");
System.out.println(s.map(Test::getOutput));
System.out.println(s.flatMap(Test::getOutputOpt));
}
static Optional<String> getOutputOpt(String input) {
return input == null ? Optional.empty() : Optional.of("output for " + input);
}
static String getOutput(String input) {
return input == null ? null : "output for " + input;
}
Both print statements print the same thing.
两个打印语句都打印相同的内容。
#2
36
They both take a function from the type of the optional to something.
它们都从可选类型中获取函数。
Map applies the function "as is" on the optional you have:
Map在您拥有的可选项上应用“原样”功能:
if (optional.isEmpty()) return Optional.empty();
else return Optional.of(f(optional.get()));
What happens if your function is a function from T -> Optional<U>
? Your result is now an Optional<Optional<U>>
!
如果你的函数是来自T - > Optional 的函数,会发生什么?您的结果现在是可选 <可选 >!
That's what flatMap
is about: if your function already returns an Optional
, flatMap
is a bit smarter and doesn't double wrap it, returning Optional<U>
. It's the composition of two functional idioms: map
and flatten
.
这就是flatMap的意思:如果你的函数已经返回一个Optional,那么flatMap有点聪明并且没有双重包装,返回Optional 。它是两个功能成语的组成:map和flatten。
#3
4
Note:- below is the illustration of map and flatmap function, otherwise Optional is primarily designed to be used as a return type only.
注意: - 下面是map和flatmap函数的图示,否则Optional主要设计为仅用作返回类型。
As you already may know Optional is a kind of container which may or may not contain a single object, so it can be used wherever you anticipate a null value(You may never see NPE if use Optional properly). For example if you have a method which expects a person object which may be nullable you may want to write the method something like this:
您可能已经知道Optional是一种容器,可能包含也可能不包含单个对象,因此可以在预期空值的任何地方使用它(如果正确使用Optional,您可能永远不会看到NPE)。例如,如果你有一个方法需要一个可以为空的person对象,你可能想要写这样的方法:
void doSome(Optional<Person> person){
/*and here you want to retrieve some property phone out of person
you may write something like this:
*/
Optional<String> phone = person.map((p)->p.getPhone());
phone.ifPresent((ph)->dial(ph));
}
class Person{
private String phone;
//setter, getters
}
Here you have returned a String type which is automatically wrapped in an Optional type.
在这里,您返回了一个String类型,它自动包装在Optional类型中。
If person class looked like this, i.e. phone is also Optional
如果人员班级看起来像这样,即电话也是可选的
class Person{
private Optional<String> phone;
//setter,getter
}
In this case invoking map function will wrap the returned value in Optional and yield something like:
在这种情况下,调用map函数会将返回的值包装在Optional中,并产生如下内容:
Optional<Optional<String>>
//And you may want Optional<String> instead, here comes flatMap
void doSome(Optional<Person> person){
Optional<String> phone = person.flatMap((p)->p.getPhone());
phone.ifPresent((ph)->dial(ph));
}
PS; Never call get method (if you need to) on an Optional without checking it with isPresent() unless you can't live without NullPointerExceptions.
PS;永远不要在一个Optional上调用get方法(如果你需要)而不用isPresent()检查它,除非你不能没有NullPointerExceptions。
#4
1
While already being answered someone new to Java might have not grasped this. What helped me was a look at the source code of the two functions.
虽然已经有人回答了Java新手,但可能还没有抓住这一点。帮助我的是看两个函数的源代码。
Map - wraps the result in an Optional.
Map - 将结果包装在Optional中。
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value)); //<--- wraps in an optional
}
}
flatMap - returns the 'raw' object
flatMap - 返回'raw'对象
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value)); //<--- returns 'raw' object
}
}