Java 8 – Optional.flatmap和Optional.map之间的区别

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

一个例子,将不胜感激。

如果函数返回所需的对象,则使用map如果函数返回Optional则使用map 。 例如:

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

这两个打印语句打印相同的东西。

它们都从可选types中取出一个函数。

地图在可选的项目上应用“原样”function:

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

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

这就是flatMap的意思:如果你的函数已经返回一个Optional ,那么flatMap有点聪明,不会双重包装它,返回Optional<U> 。 这是两个function成语的组成: mapflatten

正如你已经知道的,Optional是一种容器,可以包含或不包含单个对象,因此可以在任何你预期为空的地方使用(如果使用Optional,你可能永远都看不到NPE)。 例如,如果你有一个方法,期望一个人可能是空的对象,你可能想写这样的方法:

 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 } 

在这里你已经返回了一个Stringtypes,它被自动包装在一个Optionaltypes中。

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

 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; 除非你不能没有NullPointerExceptions,否则不要用isPresent()方法检查它,否则不要调用get方法(如果需要的话)。