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成语的组成: map
和flatten
。
正如你已经知道的,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方法(如果需要的话)。