问题

这两种方法有什么区别:Optional.flatMap()和Optional.map()?

一个例子将不胜感激。


#1 热门回答(89 赞)

Usemap如果该函数返回你需要的对象,或者flatMap如果该函数返回anOptional。例如:

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);
}

两个打印语句都打印相同的内容。


#2 热门回答(37 赞)

它们都从可选类型中获取函数。

Map在你拥有的可选项上应用"原样"功能:

if (optional.isEmpty()) return Optional.empty();
else return Optional.of(f(optional.get()));

如果你的函数来自T -> Optional<U>,会发生什么?你的结果现在是anOptional<Optional<U>>

那是什么flatMap是关于:如果你的函数已经返回一个更聪明的Optional,flatMap并且没有双重包装它,返回Optional<U>。它是两个功能成语的组成:mapflatten


#3 热门回答(4 赞)

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

如果人员班级看起来像这样,即电话也是可选的

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。


原文链接