option . flatmap()和option .map()这两个方法之间有什么区别?
请举例说明。
option . flatmap()和option .map()这两个方法之间有什么区别?
请举例说明。
当前回答
好的。你只需要使用'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;如果函数返回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 String getOutput(String input) {
return input == null ? null : "output for " + input;
}
static Optional<String> getOutputOpt(String input) {
return input == null ? Optional.empty() : Optional.of("output for " + input);
}
这两个print语句输出的是相同的东西。
好的。你只需要使用'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》。
他们做同样的事情。
唯一的区别是,lambda返回的类型被Optional或非Optional包装。
正常使用时,map比flatMap短
例子:
package bj;
import java.util.Optional;
import static java.lang.System.out;
public class App {
public static void main(String[] args) {
out.println(Optional.of(10).map (x -> x * x));
out.println(Optional.of(10).flatMap(x -> Optional.of(x * x)));
out.println(Optional.of(10).map (x -> Optional.of(x * x).get()));
out.println(Optional.<Integer>empty().map (x -> x * x));
out.println(Optional.<Integer>empty().flatMap(x -> Optional.of(x * x)));
out.println(Optional.<Integer>empty().map (x -> Optional.of(x * x).get()));
}
}
输出:
Optional[100]
Optional[100]
Optional[100]
Optional.empty
Optional.empty
Optional.empty
它们都从可选类型中取一个函数。
Map()在你拥有的可选对象上应用函数"as is":
if (optional.isEmpty()) return Optional.empty();
else return Optional.of(f(optional.get()));
如果你的函数是T ->可选<U>的函数会发生什么? 你的结果现在是一个Optional<Optional<U>>!
这就是flatMap()的意义所在:如果你的函数已经返回了一个Optional, flatMap()会更聪明一点,不会将它双换行,返回Optional<U>。
它是map和flatten这两个功能习语的组合。
你可以参考下面的链接来详细了解(这是我能找到的最好的解释):
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)