flatMap en Java

Mohammad Irfan 12 octubre 2023
  1. La función flatMap en Java
  2. Cómo utilizar el método flatMap() en Java
  3. Eliminar duplicado de flatMap en Java
  4. Filtrar elementos flatMap en Java
  5. flatMap y tipo primitivo
  6. Conclusión
flatMap en Java

Este tutorial presenta flatMap y cómo usarlo en Java.

flatMap es una operación/función en el flujo de Java que se utiliza para obtener un nuevo flujo después de realizar alguna tarea funcional. Aquí, hablaremos sobre la operación flatMap().

Esta operación es una extensión de la operación map(). Esta función se aplica a cada elemento de flujo y genera un flujo de nuevos valores.

Los elementos generados de estos nuevos flujos se copian luego en un flujo creado recientemente, que sirve como valor de retorno del método.

La función flatMap en Java

La firma de la función flatMap() es:

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

flatMap es una operación intermedia. Las operaciones intermedias son operaciones perezosas y se invocan en una instancia de Stream, y después de que finalizan su procesamiento, devuelven una instancia de Stream.

La operación flatMap() es una combinación de las operaciones map() y flat(). Esto significa que la operación flatMap() primero aplica la operación map() y luego aplana el resultado.

Este método toma un mapeador, una función que se aplicará a cada elemento del Stream entrante.

Aplanamiento en Java

Entendamos primero qué es aplanar. Aplanar una lista convierte dos o más listas de nivel en una lista de un solo nivel.

Un ejemplo de una lista de dos niveles es:

[[ "I" ], [ "Love" ], [ "Delft", "Stack" ]]

La lista anterior después de aplanar se convierte en:

["I", "Love", "Delft", "Stack"]

La lista producida es una lista de un solo nivel.

Necesidad de aplanar una lista

Es necesario aplanar una lista porque tratar con varios niveles de Stream puede ser difícil, complicado y propenso a errores.

Podemos usar la operación Stream.flatMap() para convertir los dos niveles de Stream en un Stream de un solo nivel. Lo entenderemos usando un ejemplo más adelante en este artículo.

Cómo utilizar el método flatMap() en Java

En este ejemplo, primero creamos una secuencia de objetos a partir de una Lista utilizando el método stream(). Cada objeto es un programador en una empresa.

Primero crearemos una clase para representar a un desarrollador/programador en una empresa.

import java.util.HashSet;
import java.util.Set;
class Programmer {
  private String name;
  private Set<String> languages_known;

  public Programmer(String name) {
    this.name = name;
    this.languages_known = new HashSet<>();
  }

  public void addLanguage(String lang) {
    this.languages_known.add(lang);
  }

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

Ahora inicializaremos los objetos y crearemos una lista de listas que contengan todos los lenguajes conocidos por los programadores en toda la empresa. Luego aplanaremos esa lista para conocer todos los idiomas del equipo.

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class SimpleTesting {
  public static void main(String[] args) {
    Programmer raj = new Programmer("Raj");
    raj.addLanguage("Java");
    raj.addLanguage("Dart");
    raj.addLanguage("go");
    raj.addLanguage("groovy");

    Programmer karan = new Programmer("Karan");
    karan.addLanguage("Java");
    karan.addLanguage("Python");

    Programmer chahal = new Programmer("Chahal");
    chahal.addLanguage("Dart");
    chahal.addLanguage("Javascript");

    List<Programmer> team = new ArrayList<>();
    team.add(raj);
    team.add(karan);
    team.add(chahal);

    System.out.println("Programming languages in the team: ");
    List<String> languages = team.stream()
                                 .map(Programmer::getLanguages)
                                 .flatMap(Collection::stream)
                                 .collect(Collectors.toList());
    System.out.println(languages);
  }
}

Producción :

Programming languages in the team: 
[Java, groovy, go, Dart, Java, Python, Javascript, Dart]

En el ejemplo anterior, primero creamos una transmisión de todos los programadores usando la API de transmisión. Después de eso, creamos una secuencia de listas de lenguajes conocidos por cada programador usando la función map().

Eliminar duplicado de flatMap en Java

Luego aplanamos esta lista usando la operación flatMap() y convertimos el flujo resultante en una lista. Observe que la Lista producida tiene algunos valores duplicados; usamos la operación duplicar() para eliminarlos.

Mira el código de abajo.

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class SimpleTesting {
  public static void main(String[] args) {
    Programmer raj = new Programmer("Raj");
    raj.addLanguage("Java");
    raj.addLanguage("Dart");
    raj.addLanguage("go");
    raj.addLanguage("groovy");
    Programmer karan = new Programmer("Karan");
    karan.addLanguage("Java");
    karan.addLanguage("Python");
    Programmer chahal = new Programmer("Chahal");
    chahal.addLanguage("Dart");
    chahal.addLanguage("Javascript");
    List<Programmer> team = new ArrayList<>();
    team.add(raj);
    team.add(karan);
    team.add(chahal);
    System.out.println("Programming languages in the team: ");
    List<String> languages = team.stream()
                                 .map(Programmer::getLanguages)
                                 .flatMap(Collection::stream)
                                 .distinct()
                                 .collect(Collectors.toList());
    System.out.println(languages);
  }
}

Producción :

Programming languages in the team: 
[Java, groovy, go, Dart, Python, Javascript]

Filtrar elementos flatMap en Java

Si queremos obtener todos los idiomas excepto Dart, podemos usar la función filter() con flatMap(). Mira el código de abajo.

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class SimpleTesting {
  public static void main(String[] args) {
    Programmer raj = new Programmer("Raj");
    raj.addLanguage("Java");
    raj.addLanguage("Dart");
    raj.addLanguage("go");
    raj.addLanguage("groovy");
    Programmer karan = new Programmer("Karan");
    karan.addLanguage("Java");
    karan.addLanguage("Python");
    Programmer chahal = new Programmer("Chahal");
    chahal.addLanguage("Dart");
    chahal.addLanguage("Javascript");
    List<Programmer> team = new ArrayList<>();
    team.add(raj);
    team.add(karan);
    team.add(chahal);
    System.out.println("Programming languages in the team: ");
    List<String> languages = team.stream()
                                 .map(Programmer::getLanguages)
                                 .flatMap(Collection::stream)
                                 .distinct()
                                 .filter(x -> !x.equals("Dart"))
                                 .collect(Collectors.toList());
    System.out.println(languages);
  }
}

Producción :

Programming languages in the team:
[Java, groovy, go, Python, Javascript]

flatMap y tipo primitivo

Java Stream API también proporciona operaciones separadas como flatMapto{primitive type} para tipos de datos primitivos como int, float, long para aplanar el Stream de tipo primitivo.

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class SimpleTesting {
  public static void main(String[] args) {
    int[] Je_array = {3, 5, 2, 35, 85, 32, 23, 43, 12};
    Stream<int[]> JE_streamArray = Stream.of(Je_array);
    IntStream JE_intStream = JE_streamArray.flatMapToInt(x -> Arrays.stream(x));
    JE_intStream.forEach(x -> System.out.println(x));
  }
}

Producción :

3
5
2
35
85
32
23
43
12

Conclusión

Hemos discutido la operación flatMap() y por qué es necesaria. También discutimos cómo la API Java Stream proporciona una operación flatMap() separada para tipos de datos primitivos.

Tenga en cuenta que la operación normal flatMap() también es aplicable a tipos de datos primitivos.

Artículo relacionado - Java Stream