option . flatmap()和option .map()这两个方法之间有什么区别?

请举例说明。


当前回答

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

其他回答

对我有帮助的是查看这两个函数的源代码。

映射将结果包装在可选对象中。

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value)); //<--- wraps in an optional
    }
}

flatMap -返回'raw'对象

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value)); //<---  returns 'raw' object
    }
}

你可以参考下面的链接来详细了解(这是我能找到的最好的解释):

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)

他们做同样的事情。

唯一的区别是,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;如果函数返回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语句输出的是相同的东西。

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

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这两个功能习语的组合。