Differences between .map and .flatMap?

3

I am working with Streams (Java 8) and when I use the .stream() method it is not clear to me the difference between .map and .flatMap . What are the differences between these methods?

    
asked by RoyalUp 04.04.2016 в 13:41
source

2 answers

6

The difference is that map() returns the same number of elements as the input Stream since it is simply a projection of the input elements. In other words, each input element is transformed into an output element.

On the other hand .flatMap() , projects a list of elements of each original element and concatenates them into a single stream .

For example:

map ()

List<Integer> numeros = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4)); // [1, 2, 3, 4]

List<Integer> cuadrados = numeros
  .stream()
  .map( x -> x * x)
  .collect(Collectors.toList());

for (Integer n : cuadrados) {
  System.out.println(n);
}

// Imprime el cuadrado de los números de entrada. 4 elementos de entrada, 4 de salida
// 1
// 4
// 9
// 16

flatMap ()

List<List<Integer>> listaBidimensional = new ArrayList<List<Integer>>(Arrays.asList(
  new ArrayList<Integer>(Arrays.asList(1, 2)),
  new ArrayList<Integer>(Arrays.asList(3, 4))
));
// [
//   [1, 2],
//   [3, 4]
// ]


List<Integer> listaAplanada = listaBidimensional
  .stream()
  .flatMap( listaInterna -> listaInterna.stream())
  .collect(Collectors.toList());


for (Integer n : listaAplanada) {
  System.out.println(n);
}

// Imprime los números de entrada en una sola lista de 1 dimensión.
// 2 elementos de entrada (2 listas), 4 de salida
// 1
// 2
// 3
// 4
    
answered by 04.04.2016 / 16:50
source
4

The difference is that .map produces an output value for each input value and .flatmap produces zero output values for each input value, more or less in the following way:

map :: Stream T (I - > O) flapmap :: Stream T (I -> Stream O)

I have attached an example code:

public class Developer {
  private String name;
  private Set<String> languages;

  public Developer(String name) {
    this.languages = new HashSet<>();
    this.name = name;
  }

  public void add(String language) {
    this.languages.add(language);
  }

  public Set<String> getLanguages() {
    return languages;
  }
}

public class FlatMapTest {
  @Test
  public void flatMap() {
    List<Developer> team = new ArrayList<>();
    Developer polyglot = new Developer("experto");
    polyglot.add("clojure");
    polyglot.add("scala");
    polyglot.add("groovy");
    polyglot.add("go");

    Developer busy = new Developer("estandard");
    busy.add("java");
    busy.add("javascript");

    Developer becario = new Developer("becario");

    team.add(polyglot);
    team.add(busy);
    team.add(becario);

    List<String> teamLanguages = team.stream().
         map(d -> d.getLanguages()).
         flatMap(l -> l.stream()).
         collect(Collectors.toList());

    assertTrue(teamLanguages.containsAll(polyglot.getLanguages()));
    assertTrue(teamLanguages.containsAll(busy.getLanguages()));

  }
}
    
answered by 04.04.2016 в 16:47