option . flatmap()和option .map()这两个方法之间有什么区别?
请举例说明。
option . flatmap()和option .map()这两个方法之间有什么区别?
请举例说明。
当前回答
Optional.map ():
获取每个元素,如果值存在,则将其传递给函数:
Optional<T> optionalValue = ...;
Optional<Boolean> added = optionalValue.map(results::add);
现在added有三个值之一:true或false包装成Optional(如果optionalValue存在),否则为空Optional。
如果你不需要处理结果,你可以简单地使用ifPresent(),它没有返回值:
optionalValue.ifPresent(results::add);
可选):flatMap。(
工作原理类似于流的相同方法。使溪流变平。不同之处在于,如果值被呈现,它将被应用于函数。否则,返回一个空的可选项。
您可以使用它来组合可选值函数调用。
假设我们有一些方法:
public static Optional<Double> inverse(Double x) {
return x == 0 ? Optional.empty() : Optional.of(1 / x);
}
public static Optional<Double> squareRoot(Double x) {
return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));
}
然后你可以计算逆函数的平方根,比如:
Optional<Double> result = inverse(-4.0).flatMap(MyMath::squareRoot);
或者,如果你喜欢:
Optional<Double> result = Optional.of(-4.0)
.flatMap(MyMath::inverse)
.flatMap(MyMath::squareRoot);
如果inverse()或squareRoot()返回Optional.empty(),则结果为空。
其他回答
你可以参考下面的链接来详细了解(这是我能找到的最好的解释):
https://www.programmergirl.com/java-8-map-flatmap-difference/
map和flatMap - accept函数。map()的返回类型是单个值,而flatMap是返回值流
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
Optional.map ():
获取每个元素,如果值存在,则将其传递给函数:
Optional<T> optionalValue = ...;
Optional<Boolean> added = optionalValue.map(results::add);
现在added有三个值之一:true或false包装成Optional(如果optionalValue存在),否则为空Optional。
如果你不需要处理结果,你可以简单地使用ifPresent(),它没有返回值:
optionalValue.ifPresent(results::add);
可选):flatMap。(
工作原理类似于流的相同方法。使溪流变平。不同之处在于,如果值被呈现,它将被应用于函数。否则,返回一个空的可选项。
您可以使用它来组合可选值函数调用。
假设我们有一些方法:
public static Optional<Double> inverse(Double x) {
return x == 0 ? Optional.empty() : Optional.of(1 / x);
}
public static Optional<Double> squareRoot(Double x) {
return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));
}
然后你可以计算逆函数的平方根,比如:
Optional<Double> result = inverse(-4.0).flatMap(MyMath::squareRoot);
或者,如果你喜欢:
Optional<Double> result = Optional.of(-4.0)
.flatMap(MyMath::inverse)
.flatMap(MyMath::squareRoot);
如果inverse()或squareRoot()返回Optional.empty(),则结果为空。
对我有帮助的是查看这两个函数的源代码。
映射将结果包装在可选对象中。
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 -返回'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
}
}
好的。你只需要使用'flatMap'当你面对嵌套的可选项。下面是一个例子。
public class Person {
private Optional<Car> optionalCar;
public Optional<Car> getOptionalCar() {
return optionalCar;
}
}
public class Car {
private Optional<Insurance> optionalInsurance;
public Optional<Insurance> getOptionalInsurance() {
return optionalInsurance;
}
}
public class Insurance {
private String name;
public String getName() {
return name;
}
}
public class Test {
// map cannot deal with nested Optionals
public Optional<String> getCarInsuranceName(Person person) {
return person.getOptionalCar()
.map(Car::getOptionalInsurance) // ① leads to a Optional<Optional<Insurance>
.map(Insurance::getName); // ②
}
}
和Stream一样,Optional#map将返回一个由Optional包装的值。这就是为什么我们得到了一个嵌套的Optional—Optional<Optional<Insurance>。在②,我们想把它映射成一个保险实例,这就是悲剧发生的方式。 根是嵌套的optional。如果我们能得到核心价值,不管外壳如何,我们就能完成它。这就是flatMap所做的。
public Optional<String> getCarInsuranceName(Person person) {
return person.getOptionalCar()
.flatMap(Car::getOptionalInsurance)
.map(Insurance::getName);
}
最后,如果你想系统地学习Java8,我强烈推荐《Java8 In Action》。
注意:-下面是map和flatmap函数的说明,否则Optional主要被设计为仅用作返回类型。
你可能已经知道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
}
这里您返回了一个String类型,它自动包装在一个Optional类型中。
如果person类看起来像这样,即phone也是Optional
class Person{
private Optional<String> phone;
//setter,getter
}
在这种情况下,调用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; 永远不要在一个Optional对象上调用get方法(如果需要的话),而不使用isPresent()检查它,除非你不能没有NullPointerExceptions。