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)

注意:-下面是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。

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(),则结果为空。

如果函数返回需要的对象,则使用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语句输出的是相同的东西。

他们做同样的事情。

唯一的区别是,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