What's the difference between map and flatMap

2019-01-02 18:57发布

In Java 8, what's the difference between Stream.map and Stream.flatMap methods?

18条回答
呛了眼睛熬了心
2楼-- · 2019-01-02 19:25

Stream operations flatMap and map accept a function as input.

flatMap expects the function to return a new stream for each element of the stream and returns a stream which combines all the elements of the streams returned by the function for each element. In other words, with flatMap, for each element from the source, multiple elements will be created by the function. http://www.zoftino.com/java-stream-examples#flatmap-operation

map expects the function to return a transformed value and returns a new stream containing the transformed elements. In other words, with map, for each element from the source, one transformed element will be created by the function. http://www.zoftino.com/java-stream-examples#map-operation

查看更多
骚的不知所云
3楼-- · 2019-01-02 19:26

Also good analogy can be with C# if you familiar with. Basically C# Select similar to java map and C# SelectMany java flatMap. Same applies to Kotlin for collections.

查看更多
宁负流年不负卿
4楼-- · 2019-01-02 19:28

Suppose we have:

List<List<Integer>> lists = List.of(List.of(1, 2), List.of(3, 4));

flatMap

Let's take a Function that accepts one argument and produces a Stream of values:

Function<List<Integer>, Stream<Integer>> f = list -> list.stream();

And apply this function to each list:

for (List<Integer> list : lists) f.apply(list).forEach(System.out::print);

That's exactly what the Stream.flatMap can do:

lists.stream().flatMap(list -> list.stream()).forEach(System.out::print);

map

Let's take a Function that accepts one argument and produces one value:

Function<List<Integer>, String> f = list -> list.toString();

And apply this function to each list:

for (List<Integer> list : lists) System.out.print(f.apply(list));

That's exactly what the Stream.map can do:

lists.stream().map(list -> list.toString()).forEach(System.out::print);
查看更多
余欢
5楼-- · 2019-01-02 19:29

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

enter image description here

As you can see, with map() only:

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

and with flatMap():

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

This is the test result from the code used right below:

-------- Without flatMap() -------------------------------
     collect return: [[Laptop, Phone], [Mouse, Keyboard]]

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

Code used:

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class Parcel {
  String name;
  List<String> items;

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

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

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

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

    System.out.println("\n-------- With flatMap() ------------------------------");
    List<String> flatMapReturn = parcels.stream()
      .map(Parcel::getItems)
      .flatMap(Collection::stream)
      .collect(Collectors.toList());
    System.out.println("\t collect return: " + flatMapReturn);
  }
}
查看更多
柔情千种
6楼-- · 2019-01-02 19:30

I am not very sure I am supposed to answer this, but every time I face someone that does not understand this, I use the same example.

Imagine you have an apple. A map is transforming that apple to apple-juice for example or a one-to-one mapping.

Take that same apple and get only the seeds out of it, that is what flatMap does, or a one to many, one apple as input, many seeds as output.

查看更多
萌妹纸的霸气范
7楼-- · 2019-01-02 19:33

for a Map we have a list of elements and a (function,action) f so :

[a,b,c] f(x) => [f(a),f(b),f(c)]

and for the flat map we have a list of elements list and we have a (function,action) f and we want the result to be flattened :

[[a,b],[c,d,e]] f(x) =>[f(a),f(b),f(c),f(d),f(e)]
查看更多
登录 后发表回答