终于搞明白了map与flatmap的区别

2022-11-18 09:54:28 浏览数 (1)

map

map() method -> Data Transformation

map() takes Stream as input and return Stream

Stream map(Stream input){}

代码语言:javascript复制
 <R> Stream<R> map(Function<? super T, ? extends R> mapper);

It's mapper function produces single value for each input value.hence it is also called One-To-One mapping.

这个方法比较好理解,把一个事物映射为另一个事物,是一对一的关系。

在没有stream.map()时,就在使用apache和guava的类似api

apache中的ListUtils

代码语言:javascript复制
public static <E> List<E> transformedList(final List<E> list,final Transformer<? super E, ? extends E> transformer)

guava中的Lists

代码语言:javascript复制
public static <F, T> List<T> transform(List<F> fromList, Function<? super F, ? extends T> function)

flatMap

flatMap() -> map() Flattering

flatMap() takes Stream<Stream> as input and return Stream

Stream map(Stream<Stream> input){}

代码语言:javascript复制
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

It's mapper function produces multiple value for each input value.hence it is also called One-To-Many mapping.

flattering

flatMap()其实是两个方法的合并,map()好理解,主要是flattering。

Before Flattening: [[t,u], [v,w,x], [y,x]]

After Flattening: [t,u,v,w,x,y,x]

其实就是把两层数组打平了。

实例

在stackoverflow上找的一个示例:

What's the difference between map() and flatMap() methods in Java 8?[1]

flatMap helps to flatten a Collection<Collection> into a Collection. In the same way, it will also flatten an Optional<Optional> into Optional.

代码语言:javascript复制
public class Parcel {

    String name;
    List<String> items;

    public Parcel(final String name, final String... items) {
        this.name = name;
        this.items = Arrays.asList(items);
    }

    public List<String> getItems() {
        return items;
    }

    public static void main(final String[] args) {
        final Parcel amazon = new Parcel("amazon", "Laptop", "Phone");
        final Parcel ebay = new Parcel("ebay", "Mouse", "Keyboard");
        final List<Parcel> parcels = Arrays.asList(amazon, ebay);

        System.out.println("-------- Without flatMap() ---------------------------");
        final List<List<String>> mapReturn = parcels.stream()
            .map(Parcel::getItems)
            .collect(Collectors.toList());
        System.out.println("t collect() returns: "   mapReturn);

        System.out.println("n-------- With flatMap() ------------------------------");
        final List<String> flatMapReturn = parcels.stream()
            .map(Parcel::getItems)
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
        System.out.println("t collect() returns: "   flatMapReturn);
    }

}

结果输出:

代码语言:javascript复制
-------- Without flatMap() ---------------------------
     collect() returns: [[Laptop, Phone], [Mouse, Keyboard]]

-------- With flatMap() ------------------------------
     collect() returns: [Laptop, Phone, Mouse, Keyboard]

As you can see, with map() only:

•The intermediate type is Stream<List>•The return type is List<List>

and with flatMap():

•The intermediate type is Stream•The return type is List

References

[1] What's the difference between map() and flatMap() methods in Java 8?: https://stackoverflow.com/questions/26684562/whats-the-difference-between-map-and-flatmap-methods-in-java-8 [2] flatMap() Method in Java 8 : https://www.javatpoint.com/flatmap-method-in-java-8

0 人点赞