Qual è la differenza tra i metodi map() e flatMap() in Java 8?


In Java 8, qual è la differenza tra Stream.map() e Stream.flatMap() metodi?

Author: cassiomolin, 2014-10-31

19 answers

Sia map che flatMap possono essere applicati a un Stream<T> ed entrambi restituiscono un Stream<R>. La differenza è che l'operazione map produce un valore di output per ogni valore di input, mentre l'operazione flatMap produce un numero arbitrario (zero o più) valori per ogni valore di input.

Ciò si riflette negli argomenti di ogni operazione.

L'operazione map accetta un Function, che viene chiamato per ogni valore nel flusso di input e produce un valore di risultato, che viene inviato al flusso di uscita.

L'operazione flatMap prende una funzione che concettualmente vuole consumare un valore e produrre un numero arbitrario di valori. Tuttavia, in Java, è ingombrante per un metodo restituire un numero arbitrario di valori, poiché i metodi possono restituire solo zero o un valore. Si potrebbe immaginare un'API in cui la funzione mapper per flatMap assume un valore e restituisce un array o un List di valori, che vengono quindi inviati all'output. Dato che questa è la libreria streams, un particolare un modo adatto per rappresentare un numero arbitrario di valori restituiti è che la funzione mapper stessa restituisca un flusso! I valori del flusso restituiti dal mappatore vengono scaricati dal flusso e vengono passati al flusso di output. I " grumi "di valori restituiti da ogni chiamata alla funzione mapper non sono affatto distinti nel flusso di output, quindi si dice che l'output sia stato" appiattito."

L'uso tipico è per la funzione mapper di flatMap per restituire Stream.empty() se vuole inviare zero valori, o qualcosa come Stream.of(a, b, c) se vuole restituire diversi valori. Ma ovviamente qualsiasi flusso può essere restituito.

 905
Author: Stuart Marks, 2016-06-18 17:13:16

Stream.flatMap, come si può intuire dal suo nome, è la combinazione di un map e un flat operazione. Ciò significa che prima applichi una funzione ai tuoi elementi e poi la appiattisci. Stream.map applica solo una funzione allo stream senza appiattirlo.

Per capire in cosa consiste l'appiattimento di un flusso, considera una struttura come [ [1,2,3],[4,5,6],[7,8,9] ] che ha "due livelli". Appiattire questo significa trasformarlo in una struttura "a un livello": [ 1,2,3,4,5,6,7,8,9 ].

 589
Author: Dici, 2016-05-17 21:43:37

Vorrei dare 2 esempi per ottenere un più punto di vista pratico:
Primo esempio di utilizzo di map:

@Test
public void convertStringToUpperCaseStreams() {
    List<String> collected = Stream.of("a", "b", "hello") // Stream of String 
            .map(String::toUpperCase) // Returns a stream consisting of the results of applying the given function to the elements of this stream.
            .collect(Collectors.toList());
    assertEquals(asList("A", "B", "HELLO"), collected);
}

Niente di speciale nel primo esempio, un Function viene applicato per restituire il String in maiuscolo.

Secondo esempio facendo uso di flatMap:

@Test
public void testflatMap() throws Exception {
    List<Integer> together = Stream.of(asList(1, 2), asList(3, 4)) // Stream of List<Integer>
            .flatMap(List::stream)
            .map(integer -> integer + 1)
            .collect(Collectors.toList());
    assertEquals(asList(2, 3, 4, 5), together);
}

Nel secondo esempio, viene passato un flusso di List. NON è un flusso di Interi!
Se è necessario utilizzare una funzione di trasformazione (tramite mappa), prima lo Stream deve essere appiattito su qualcos'altro (un flusso di interi).
Se flatMapviene rimosso, viene restituito il seguente errore: L'operatore + non è definito per l'elenco dei tipi di argomenti, int.
NON è possibile applicare + 1 su un List di Numeri Interi!

 263
Author: Rudy Vissers, 2020-06-24 08:38:07

Si prega di passare attraverso il post completamente per avere un'idea chiara,

Mappa vs flatMap:

Per restituire una lunghezza di ogni parola da un elenco, faremmo qualcosa come sotto..

Versione breve riportata di seguito

Quando raccogliamo due elenchi, indicati di seguito

Senza mappa piatta => [1,2],[1,1] => [[1,2],[1,1]] Qui due liste sono posizionate all'interno di una lista, quindi l'output sarà una lista contenente elenchi

Con mappa piatta => [1,2],[1,1] => [1,2,1,1] Qui due elenchi vengono appiattiti e solo i valori vengono inseriti in list, quindi l'output sarà list contenente solo elementi

Fondamentalmente unisce tutti gli oggetti in uno

# # La versione dettagliata è stata fornita di seguito: -

Ad esempio:-
Considera una lista ["STACK", "OOOVVVER"] e stiamo cercando di restituire una lista come ["STACKOVER"] (restituendo solo lettere univoche da quell'elenco) Inizialmente, faremmo qualcosa come di seguito per restituire un elenco ["STACKOVER"] da ["STACK", "OOOVVVER"]

public class WordMap {
  public static void main(String[] args) {
    List<String> lst = Arrays.asList("STACK","OOOVER");
    lst.stream().map(w->w.split("")).distinct().collect(Collectors.toList());
  }
}

Qui il problema è che Lambda passato al metodo map restituisce un array di stringhe per ogni parola, quindi il flusso restituito dal metodo map è in realtà di tipo Stream, ma ciò di cui abbiamo bisogno è Stream per rappresentare un flusso di caratteri, sotto l'immagine illustra il problema.

Figura A:

inserisci qui la descrizione dell'immagine

Potresti pensare che possiamo risolvere questo problema usando flatmap,
OK, vediamo come risolvere questo problema usando map e Array.flusso Prima di tutto avrai bisogno di un flusso di caratteri invece di un flusso di array. Esiste un metodo chiamato Array.stream () che prende un array e produce un flusso, ad esempio:

String[] arrayOfWords = {"STACK", "OOOVVVER"};
Stream<String> streamOfWords = Arrays.stream(arrayOfWords);
streamOfWords.map(s->s.split("")) //Converting word in to array of letters
    .map(Arrays::stream).distinct() //Make array in to separate stream
    .collect(Collectors.toList());

Quanto sopra non funziona ancora, perché ora finiamo con un elenco di stream (più precisamente, Stream>), invece, dobbiamo prima convertire ogni parola in una matrice di singole lettere e quindi trasformare ogni array in un flusso separato

Usando flatMap dovremmo essere in grado di risolvere questo problema come di seguito:

String[] arrayOfWords = {"STACK", "OOOVVVER"};
Stream<String> streamOfWords = Arrays.stream(arrayOfWords);
streamOfWords.map(s->s.split("")) //Converting word in to array of letters
    .flatMap(Arrays::stream).distinct() //flattens each generated stream in to a single stream
    .collect(Collectors.toList());

FlatMap eseguirebbe la mappatura di ogni array non con stream ma con il contenuto di quel flusso. Tutti i singoli flussi che verrebbero generati durante l'utilizzo di map(Arrays::stream) vengono uniti in un singolo flusso. La figura B illustra l'effetto dell'utilizzo del metodo flatMap. Confrontalo con ciò che la mappa fa nella figura A. Figura B inserisci qui la descrizione dell'immagine

Il metodo flatMap consente di sostituire ogni valore di un flusso con un altro flusso e quindi unire tutti i flussi generati in un singolo flusso.

 182
Author: TechDog, 2019-05-13 02:51:15

Una risposta di riga: flatMap aiuta ad appiattire un Collection<Collection<T>> in un Collection<T>. Allo stesso modo, appiattirà anche un Optional<Optional<T>> in Optional<T>.

inserisci qui la descrizione dell'immagine

Come puoi vedere, con map() solo:

  • Il tipo intermedio è Stream<List<Item>>
  • Il tipo di ritorno è List<List<Item>>

E con flatMap():

  • Il tipo intermedio è Stream<Item>
  • Il tipo restituito è List<Item>

Questo è il risultato del test dal codice usato qui sotto:

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

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

Codice utilizzato:

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() returns: " + 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() returns: " + flatMapReturn);
  }
}
 127
Author: Hoa Nguyen, 2019-04-02 14:47:11

La funzione che passi a stream.map deve restituire un oggetto. Ciò significa che ogni oggetto nel flusso di input produce esattamente un oggetto nel flusso di output.

La funzione passata a stream.flatMap restituisce un flusso per ogni oggetto. Ciò significa che la funzione può restituire qualsiasi numero di oggetti per ogni oggetto di input (incluso nessuno). I flussi risultanti vengono quindi concatenati a un flusso di output.

 46
Author: Philipp, 2014-10-31 22:58:56

Per una mappa abbiamo un elenco di elementi e una (funzione,azione) f così:

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

E per la mappa piatta abbiamo una lista di elementi list e abbiamo una (funzione,azione) f e vogliamo che il risultato sia appiattito:

[[a,b],[c,d,e]] f(x) =>[f(a),f(b),f(c),f(d),f(e)]
 32
Author: Bachiri Taoufiq Abderrahman, 2017-10-08 03:19:10

Ho la sensazione che la maggior parte delle risposte qui complichi eccessivamente il semplice problema. Se hai già capito come funziona map, dovrebbe essere abbastanza facile da afferrare.

Ci sono casi in cui possiamo finire con strutture nidificate indesiderate quando si utilizza map(), il metodo flatMap() è progettato per superare questo evitando il wrapping.


Esempi:

1

List<List<Integer>> result = Stream.of(Arrays.asList(1), Arrays.asList(2, 3))
  .collect(Collectors.toList());

Possiamo evitare di avere liste nidificate usando flatMap:

List<Integer> result = Stream.of(Arrays.asList(1), Arrays.asList(2, 3))
  .flatMap(i -> i.stream())
  .collect(Collectors.toList());

2

Optional<Optional<String>> result = Optional.of(42)
      .map(id -> findById(id));

Optional<String> result = Optional.of(42)
      .flatMap(id -> findById(id));

Dove:

private Optional<String> findById(Integer id)
 28
Author: Grzegorz Piwowarek, 2018-04-15 20:08:16

.la mappa è per A -> B mappatura

Stream.of("dog", "cat")              // stream of 2 Strings
    .map(s -> s.length())            // stream of 2 Integers: [3, 3]

converte qualsiasi elemento A in qualsiasi elemento B. Javadoc


.flatMap è per A -> Stream< B> concaturazione

Stream.of("dog", "cat")             // stream of 2 Strings
    .flatMapToInt(s -> s.chars())   // stream of 6 ints:      [d, o, g, c, a, t]

converts 1 converte qualsiasi elemento A in Stream< B>, quindi --2 concatena tutti i flussi in un unico flusso (piatto). Javadoc


Nota 1: Sebbene quest'ultimo esempio flats a un flusso di primitive (IntStream) invece di un flusso di oggetti (Stream), illustra ancora l'idea del .flatMap.

Nota 2: Nonostante il nome, Stringa.il metodo chars () restituisce ints. Quindi la raccolta effettiva sarà: [100, 111, 103, 99, 97, 116] , dove {[10] } è il codice di 'd', 111 è il codice di 'o' ecc. Ancora una volta, a scopo illustrativo, viene presentato come [d, o, g, c, a, t].

 26
Author: epox, 2020-06-24 11:38:37

L'articolo di Oracle su Optional evidenzia questa differenza tra map e flatmap:

String version = computer.map(Computer::getSoundcard)
                  .map(Soundcard::getUSB)
                  .map(USB::getVersion)
                  .orElse("UNKNOWN");

Sfortunatamente, questo codice non viene compilato. Perché? Il computer variabile è di tipo Optional<Computer>, quindi perfettamente corretto chiamare il metodo mappa. Tuttavia, getSoundcard () restituisce un oggetto di tipo Opzionale. Ciò significa che il risultato dell'operazione mappa è un oggetto del tipo Optional<Optional<Soundcard>>. Di conseguenza, la chiamata a getUSB () non è valido perché l'opzione più esterna contiene come valore un altro opzionale, che ovviamente non supporta getUSB() metodo.

Con i flussi, il metodo flatMap accetta una funzione come argomento, che restituisce un altro flusso. Questa funzione viene applicata a ciascun elemento di un flusso, che si tradurrebbe in un flusso di flussi. Tuttavia, flatMap ha l'effetto di sostituire ogni flusso generato dal contenuto di quel flusso. In altre parole, tutti i flussi separati che sono generati dalla funzione get amalgamated o " appiattito" in uno flusso singolo. Quello che vogliamo qui è qualcosa di simile, ma vogliamo "appiattire" un optional a due livelli in uno.

Opzionale supporta anche un metodo flatMap. Il suo scopo è quello di applicare la funzione di trasformazione sul valore di un Optional (proprio come la mappa operazione fa) e quindi appiattire il risultante Opzionale a due livelli in uno solo.

Quindi, per rendere corretto il nostro codice, dobbiamo riscriverlo come segue usando Mappa piatta:

String version = computer.flatMap(Computer::getSoundcard)
                   .flatMap(Soundcard::getUSB)
                   .map(USB::getVersion)
                   .orElse("UNKNOWN");

La prima flatMap assicura che venga restituito un Optional<Soundcard> invece di un Optional<Optional<Soundcard>>, e la seconda flatMap raggiunge lo stesso scopo di restituire un Optional<USB>. Si noti che il la terza chiamata deve solo essere una map () perché getVersion () restituisce a Stringa piuttosto che un oggetto opzionale.

Http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html

 23
Author: Rusty Core, 2017-02-24 20:22:21

Mappa () e flatMap()

  1. map()

Prende solo una funzione un lambda param dove T è elemento e R l'elemento di ritorno costruito usando T. Alla fine avremo un flusso con oggetti di tipo R. Un semplice esempio può essere:

Stream
  .of(1,2,3,4,5)
  .map(myInt -> "preFix_"+myInt)
  .forEach(System.out::println);

Prende semplicemente gli elementi da 1 a 5 del tipo Integer, usa ogni elemento per creare un nuovo elemento dal tipo String con valore "prefix_"+integer_value e lo stampa.

  1. flatMap()

È utile sapere che flatMap() accetta una funzione F<T, R> dove

  • T è un tipo da che un flusso può essere costruito da/con. Può essere una lista (T. stream ()), un array (Array.flusso (someArray)), ecc.. tutto ciò da cui un Flusso può essere con / o modulo. nell'esempio seguente ogni dev ha molte lingue, quindi dev. Languages è una lista e utilizzerà un parametro lambda.

  • R è il flusso risultante che verrà costruito usando T. Sapendo che abbiamo molte istanze di T, noi avranno naturalmente molti flussi da R. Tutti questi flussi dal tipo R saranno ora combinati in un unico flusso "piatto" dal tipo R.

Esempio

Gli esempi di Bachiri Taoufiq vedi la sua risposta qui sono semplici e facili da capire. Solo per chiarezza, diciamo che abbiamo un team di sviluppatori:

dev_team = {dev_1,dev_2,dev_3}

, con ogni sviluppatore che conosce molte lingue:

dev_1 = {lang_a,lang_b,lang_c},
dev_2 = {lang_d},
dev_2 = {lang_e,lang_f}

Applicazione del flusso .mappa () su dev_team per ottenere le lingue di ogni dev:

dev_team.map(dev -> dev.getLanguages())

Ti darà questa struttura:

{ 
  {lang_a,lang_b,lang_c},
  {lang_d},
  {lang_e,lang_f}
}

Che è fondamentalmente un List<List<Languages>> /Object[Languages[]]. Non così molto carina, né Java8-like!!

Con Stream.flatMap() puoi 'appiattire' le cose mentre prende la struttura sopra
e lo trasforma in {lang_a, lang_b, lang_c, lang_d, lang_e, lang_f}, che può fondamentalmente essere usato come List<Languages>/Language[]/etc...

Quindi, alla fine, il tuo codice avrebbe più senso in questo modo:

dev_team
   .stream()    /* {dev_1,dev_2,dev_3} */
   .map(dev -> dev.getLanguages()) /* {{lang_a,...,lang_c},{lang_d}{lang_e,lang_f}}} */
   .flatMap(languages ->  languages.stream()) /* {lang_a,...,lang_d, lang_e, lang_f} */
   .doWhateverWithYourNewStreamHere();

O semplicemente:

dev_team
       .stream()    /* {dev_1,dev_2,dev_3} */
       .flatMap(dev -> dev.getLanguages().stream()) /* {lang_a,...,lang_d, lang_e, lang_f} */
       .doWhateverWithYourNewStreamHere();

Quando usare map () e usare Mappa piatta():

  • Usa map()quando ogni elemento di tipo T dal tuo flusso dovrebbe essere mappato/trasformato in un singolo elemento di tipo R. Il risultato è una mappatura di tipo (1 elemento iniziale -> 1 elemento finale) e viene restituito un nuovo flusso di elementi di tipo R.

  • Usa flatMap() quando ogni elemento di tipo T dal tuo flusso dovrebbe essere mappato / trasformato in Raccolte di elementi di tipo R. Il risultato è una mappatura di tipo (1 elemento iniziale -> n elementi finali). Queste Raccolte vengono quindi unite (o appiattite ) in un nuovo flusso di elementi di tipo R. Ciò è utile ad esempio per rappresentare loop nidificati .

Pre Java 8:

List<Foo> myFoos = new ArrayList<Foo>();
    for(Foo foo: myFoos){
        for(Bar bar:  foo.getMyBars()){
            System.out.println(bar.getMyName());
        }
    }

Post Java 8

myFoos
    .stream()
    .flatMap(foo -> foo.getMyBars().stream())
    .forEach(bar -> System.out.println(bar.getMyName()));
 22
Author: arthur, 2020-02-26 11:59:35

Non sono molto sicuro di dover rispondere a questo, ma ogni volta che affronto qualcuno che non lo capisce, uso lo stesso esempio.

Immagina di avere una mela. Un map sta trasformando quella mela in apple-juice ad esempio o una mappatura uno a uno .

Prendi quella stessa mela e prendi solo i semi, questo è ciò che fa flatMap, o un uno a molti , una mela come input, molti semi come output.

 18
Author: Eugene, 2018-09-09 21:03:54

Cartina:- Questo metodo accetta una funzione come argomento e restituisce un nuovo flusso costituito dai risultati generati applicando la funzione passata a tutti gli elementi del flusso.

Immaginiamo, ho un elenco di valori interi ( 1,2,3,4,5 ) e un'interfaccia di funzione la cui logica è quadrata del numero intero passato. (e -> e * e ).

List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> newList = intList.stream().map( e -> e * e ).collect(Collectors.toList());

System.out.println(newList);

Uscita: -

[1, 4, 9, 16, 25]

Come puoi vedere, un output è un nuovo flusso i cui valori sono quadrati dei valori dell'input flusso.

[1, 2, 3, 4, 5] -> apply e -> e * e -> [ 1*1, 2*2, 3*3, 4*4, 5*5 ] -> [1, 4, 9, 16, 25 ]

Http://codedestine.com/java-8-stream-map-method /

Mappa piatta :- Questo metodo accetta una funzione come argomento, questa funzione accetta un parametro T come argomento di input e restituisce un flusso di parametro R come valore di ritorno. Quando questa funzione viene applicata a ciascun elemento di questo flusso, produce un flusso di nuovi valori. Tutti gli elementi di questi nuovi flussi generati da ciascun elemento vengono quindi copiati in un nuovo flusso, che sarà un valore restituito di questo metodo.

Immaginiamo, ho una lista di oggetti studente, in cui ogni studente può optare per più soggetti.

List<Student> studentList = new ArrayList<Student>();

  studentList.add(new Student("Robert","5st grade", Arrays.asList(new String[]{"history","math","geography"})));
  studentList.add(new Student("Martin","8st grade", Arrays.asList(new String[]{"economics","biology"})));
  studentList.add(new Student("Robert","9st grade", Arrays.asList(new String[]{"science","math"})));

  Set<Student> courses = studentList.stream().flatMap( e -> e.getCourse().stream()).collect(Collectors.toSet());

  System.out.println(courses);

Uscita: -

[economics, biology, geography, science, history, math]

Come puoi vedere, un output è un nuovo flusso i cui valori sono una raccolta di tutti gli elementi dei flussi restituiti da ciascun elemento del flusso di input.

[S1 , S2 , S3] - > [{"storia", "matematica", "geografia"}, {"economia"," biologia"}, {"scienza", "matematica"}] - > prendere soggetti unici - > [economia, biologia, geografia, scienza, storia, matematica]

Http://codedestine.com/java-8-stream-flatmap-method /

 13
Author: lalitbhagtani, 2018-07-27 14:51:17

Se pensi che map() sia un'iterazione(un ciclo for di un livello), flatmap() è un'iterazione a due livelli(come un ciclo for annidato). (Inserire ogni elemento iterato foo, e fare foo.getBarList() e iterare in quel barList di nuovo)


map(): prendi un flusso, fai qualcosa per ogni elemento, raccogli il singolo risultato di ogni processo, emetti un altro flusso. La definizione di" do something function " è implicita. Se l'elaborazione di qualsiasi elemento risulta in null, null viene utilizzato per comporre il flusso finale. Quindi, il numero di elementi nel flusso risultante sarà uguale al numero di flusso di input.

flatmap(): prendi un flusso di elementi / flussi e una funzione(definizione esplicita), applica la funzione a ciascun elemento di ciascun flusso e raccogli tutto il flusso risultante intermedio per essere un flusso maggiore("appiattimento"). Se l'elaborazione di qualsiasi elemento risulta in null, il flusso vuoto viene fornito alla fase finale di "appiattimento". Il numero di elementi nel flusso risultante, è il totale di tutti gli elementi partecipanti in tutti gli ingressi, se l'ingresso è più flussi.

 3
Author: WesternGun, 2019-11-29 13:07:32

Risposta semplice.

L'operazione map può produrre un Stream di Stream.EX Stream<Stream<Integer>>

flatMap l'operazione produrrà solo Stream di qualcosa. EX Stream<Integer>

 2
Author: Melad Basilius, 2019-03-15 14:44:09

Anche una buona analogia può essere con c# se hai familiarità con. Fondamentalmente C #Select simile a java map e c# SelectMany java flatMap. Lo stesso vale per Kotlin per le collezioni.

 1
Author: Arsenius, 2017-06-14 04:12:30

Questo è molto confuso per i principianti. La differenza fondamentale è che map emette un elemento per ogni voce nell'elenco e flatMap è fondamentalmente un map + flatten operazione. Per essere più chiari, usa flatMap quando hai bisogno di più di un valore, ad esempio quando ti aspetti un ciclo per restituire gli array, flatMap sarà davvero utile in questo caso.

Ho scritto un blog su questo, è possibile controllare qui.

 1
Author: Niraj Chauhan, 2017-10-27 07:43:23

Le operazioni di flusso flatMap e map accettano una funzione come input.

flatMap si aspetta che la funzione restituisca un nuovo flusso per ogni elemento del flusso e restituisce un flusso che combina tutti gli elementi dei flussi restituiti dalla funzione per ogni elemento. In altre parole, con flatMap, per ogni elemento dall'origine, verranno creati più elementi dalla funzione. http://www.zoftino.com/java-stream-examples#flatmap-operation

map si aspetta la funzione per restituire un valore trasformato e restituisce un nuovo flusso contenente gli elementi trasformati. In altre parole, con map, per ogni elemento dall'origine, verrà creato un elemento trasformato dalla funzione. http://www.zoftino.com/java-stream-examples#map-operation

 1
Author: Arnav Rao, 2018-07-27 13:09:28

flatMap() sfrutta anche la valutazione parziale pigra dei flussi. Leggerà il flusso pugno e solo quando richiesto, andrà al flusso successivo. Il comportamento è spiegato in dettaglio qui: flatMap è garantito per essere pigro?

 0
Author: S.K., 2018-09-24 17:36:11