Jaka jest różnica między metodami map() i flatMap () w Javie 8?

W Javie 8, jaka jest różnica między Stream.map() oraz Stream.flatMap() metody?

Author: cassiomolin, 2014-10-31

19 answers

Zarówno map jak i flatMap można zastosować do Stream<T> i obie zwracają Stream<R>. Różnica polega na tym, że operacja map generuje jedną wartość wyjściową dla każdej wartości wejściowej, podczas gdy operacja flatMap generuje dowolną liczbę (zero lub więcej) wartości dla każdej wartości wejściowej.

Znajduje to odzwierciedlenie w argumentach każdej operacji.

Operacja map pobiera Function, która jest wywoływana dla każdej wartości w strumieniu wejściowym i generuje jedną wartość wynikową, która jest wysyłana do strumień wyjściowy.

Operacja flatMap przyjmuje funkcję, która koncepcyjnie chce zużyć jedną wartość i wytworzyć dowolną liczbę wartości. Jednak w języku Java kłopotliwe jest zwracanie przez metodę dowolnej liczby wartości, ponieważ metody mogą zwracać tylko zero lub jedną wartość. Można sobie wyobrazić API, w którym funkcja mapera dla flatMap pobiera wartość i zwraca tablicę lub List wartości, które są następnie wysyłane na wyjście. Biorąc pod uwagę, że jest to biblioteka strumieni, a szczególnie apt sposobem na reprezentowanie dowolnej liczby zwracanych wartości jest zwrócenie strumienia przez samą funkcję mapera! Wartości ze strumienia zwróconego przez mapera są odprowadzane ze strumienia i przekazywane do strumienia wyjściowego. "Kępki" wartości zwracanych przez każde wywołanie funkcji mapera nie są w ogóle rozróżniane w strumieniu wyjściowym, więc wyjście jest uważane za "spłaszczone"."

Typowe użycie funkcji mapper flatMap zwraca Stream.empty() jeśli chce wysłać zero wartości, lub coś w stylu Stream.of(a, b, c), jeśli chce zwrócić kilka wartości. Ale oczywiście każdy strumień może zostać zwrócony.

 905
Author: Stuart Marks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-18 17:13:16

Stream.flatMap, jak można się domyślić po nazwie, jest kombinacją operacji map i flat. Oznacza to, że najpierw zastosujesz funkcję do swoich elementów, a następnie spłaszczysz ją. Stream.map stosuje tylko funkcję do strumienia bez spłaszczania strumienia.

Aby zrozumieć na czym polega spłaszczenie strumienia, rozważ strukturę podobną do [ [1,2,3],[4,5,6],[7,8,9] ], która ma "dwa poziomy". Spłaszczenie oznacza przekształcenie go w strukturę "jednopoziomową": [ 1,2,3,4,5,6,7,8,9 ].

 589
Author: Dici,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-17 21:43:37

Chciałbym podać 2 przykłady, aby uzyskać więcej praktyczny punkt widzenia:
pierwszy przykład użycia 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);
}

Nic specjalnego w pierwszym przykładzie zastosowano Function, aby zwrócić String wielkimi literami.

Drugi przykład użycia 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);
}

W drugim przykładzie przekazywany jest strumień listy. to nie jest strumień liczby całkowitej!
jeśli ma być użyta funkcja transformacji (poprzez mapę), to najpierw strumień musi być spłaszczony do czegoś innego (strumień liczby całkowitej).
Jeśli flatMap jest usunięty, zwracany jest następujący błąd: operator + jest niezdefiniowany dla listy typów argumentów, int.
nie można zastosować + 1 na List liczb całkowitych!

 263
Author: Rudy Vissers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-24 08:38:07

Proszę przejść przez post w pełni, aby uzyskać jasny pomysł,

Mapa vs flatMap:

Aby zwrócić długość każdego słowa z listy, zrobimy coś takiego jak poniżej..

Krótka wersja podana poniżej

Kiedy zbieramy dwie listy, podane poniżej

bez Mapa płaska => [1,2],[1,1] => [[1,2],[1,1]] tutaj dwie listy są umieszczone wewnątrz listy, więc wyjście będzie listą zawierającą listy

z Mapa płaska => [1,2],[1,1] => [1,2,1,1] tutaj dwie listy są spłaszczone i tylko wartości są umieszczane w liście, więc wyjście będzie listą zawierającą tylko elementy

Zasadniczo łączy wszystkie obiekty w jeden

# # szczegółowa wersja została podana poniżej: -

Na przykład:-
rozważmy listę ["STACK","OOOVVVER"] i staramy się zwrócić listę taką jak ["STACKOVER"] (zwracanie tylko unikalnych liter z tej listy) Początkowo zrobimy coś takiego jak poniżej, aby zwrócić listę ["STACKOVER"] z ["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());
  }
}

Tutaj problem polega na tym, że Lambda przekazywana do metody map zwraca tablicę łańcuchów dla każdego słowa, więc strumień zwracany przez metodę map jest rzeczywiście typu Stream, ale potrzebujemy strumienia do reprezentowania strumienia znaków, poniżej obrazek ilustruje problem.

Rysunek A:

Tutaj wpisz opis obrazka

Możesz pomyśleć, że możemy rozwiązać ten problem używając flatmap,
OK, zobaczmy jak rozwiązać ten problem używając tablic map i .stream Przede wszystkim będziesz potrzebował strumienia znaków zamiast strumienia tablic. Istnieje metoda zwana tablicami.stream (), które pobierze tablicę i wytworzy strumień, na przykład:

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());

Powyższe nadal nie działa, ponieważ teraz kończy się z listą strumieni (dokładniej Stream>), zamiast tego musimy najpierw przekonwertować każde słowo na tablicę pojedynczych liter, a następnie uczynić każdą tablicę osobnym strumieniem

Używając flatMap powinniśmy być w stanie rozwiązać ten problem jak poniżej:

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 wykona mapowanie każdej tablicy nie ze strumieniem, ale z zawartością tego strumienia. Wszystkie poszczególne strumienie, które zostaną wygenerowane podczas korzystania z map (Arrays:: stream), zostaną scalone w jeden strumień. Rysunek B ilustruje efekt zastosowania metody flatMap. Porównaj to z tym, co robi mapa na rysunku A. Rysunek B Tutaj wpisz opis obrazka

Metoda flatMap umożliwia zastąpienie każdej wartości strumienia innym strumieniem, a następnie połączenie wszystkich wygenerowanych strumieni w jeden strumień.

 182
Author: TechDog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-13 02:51:15

Odpowiedź w jednej linijce: flatMap pomaga spłaszczyć Collection<Collection<T>> w Collection<T>. W ten sam sposób, będzie również spłaszczyć Optional<Optional<T>> do Optional<T>.

Tutaj wpisz opis obrazka

Jak widać, z map() tylko:

  • typem pośrednim jest Stream<List<Item>>
  • typem zwracanym jest List<List<Item>>

I z flatMap():

  • typem pośrednim jest Stream<Item>
  • Typ powrotu to List<Item>

To jest wynik testu z kodu użytego poniżej:

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

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

Użyty kod :

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-02 14:47:11

Funkcja, którą przekazujesz {[0] } musi zwrócić jeden obiekt. Oznacza to, że każdy obiekt w strumieniu wejściowym daje dokładnie jeden obiekt w strumieniu wyjściowym.

Przekazywana funkcja stream.flatMap zwraca strumień dla każdego obiektu. Oznacza to, że funkcja może zwrócić dowolną liczbę obiektów dla każdego obiektu wejściowego (łącznie z none). Powstałe strumienie są następnie łączone do jednego strumienia wyjściowego.

 46
Author: Philipp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-31 22:58:56

Dla mapy mamy listę elementów i a (funkcja,akcja) f więc:

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

I dla mapy płaskiej mamy listę elementów list i mamy (funkcję, akcję) f i chcemy, aby wynik był spłaszczony:

[[a,b],[c,d,e]] f(x) =>[f(a),f(b),f(c),f(d),f(e)]
 32
Author: Bachiri Taoufiq Abderrahman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-08 03:19:10

Mam wrażenie, że większość odpowiedzi tutaj komplikuje prosty problem. Jeśli już rozumiesz, jak działa map, powinno to być dość łatwe do zrozumienia.

Są przypadki, w których możemy skończyć z niechcianymi strukturami zagnieżdżonymi przy użyciu map(), metoda flatMap() jest zaprojektowana w celu przezwyciężenia tego poprzez unikanie owijania.


Przykłady:

1

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

Możemy uniknąć zagnieżdżania list używając 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));

Gdzie:

private Optional<String> findById(Integer id)
 28
Author: Grzegorz Piwowarek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-15 20:08:16

.Mapa jest dla A -> B mapowanie

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

konwertuje dowolny element A na dowolny element B. Javadoc


.flatMap jest dla A -> Stream< B> konkatinacja

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

to --1 zamienia dowolny element A na Stream< B>, Następnie --2 łączy wszystkie strumienie w jeden (płaski) strumień. Javadoc


Uwaga 1: Chociaż ten ostatni przykład prymitywy (IntStream) zamiast strumienia obiektów (Stream), nadal ilustruje ideę .flatMap.

Uwaga 2: pomimo nazwy, ciąg znaków.metoda chars () zwraca ints. Tak więc zbiór rzeczywisty będzie: [100, 111, 103, 99, 97, 116] , gdzie 100 jest kodem 'd', 111 jest kodem 'o' itd. Ponownie, dla celów ilustracyjnych, jest przedstawiony jako [d, o, g, c, a, t].

 26
Author: epox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-24 11:38:37

[[7]} artykuł Oracle na temat opcji podkreśla tę różnicę między mapą a flatmapą:

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

Niestety ten kod nie jest kompilowany. Dlaczego? Zmienny komputer jest typu Optional<Computer>, więc idealnie poprawne jest wywołanie metoda map. Jednak getSoundcard () zwraca obiekt typu Opcjonalnie. Oznacza to, że wynikiem działania mapy jest obiekt typu Optional<Optional<Soundcard>>. W rezultacie wezwanie do getUSB() jest niepoprawne, ponieważ opcja zewnętrzna zawiera jako swoją wartość kolejny opcjonalny, który oczywiście nie obsługuje getUSB() metoda.

W przypadku strumieni metoda flatMap przyjmuje funkcję jako argument, który zwraca inny strumień. Funkcja ta jest stosowana do każdego elementu strumienia, co spowodowałoby powstanie strumienia strumieni. Jednakże, flatMap ma efekt zastąpienia każdego wygenerowanego strumienia przez zawartość tego strumienia. Innymi słowy, wszystkie odrębne strumienie, które są generowane przez funkcję get amalgamated lub " spłaszczone" w jeden pojedynczy strumień. Chcemy tu czegoś podobnego, ale chcemy "spłaszczyć" dwupoziomowy opcjonalny w jeden .

Opcjonalne obsługuje również metodę flatMap. Jego celem jest zastosowanie funkcja transformacji na wartości opcjonalnej (podobnie jak mapa operacji robi), a następnie spłaszczyć wynikowy dwupoziomowy opcjonalny do jeden .

Więc, aby nasz kod był poprawny, musimy go przepisać w następujący sposób za pomocą flatMap:

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

Pierwsza flatMap zapewnia, że Optional<Soundcard> jest zwracana zamiast Optional<Optional<Soundcard>>, a druga flatmapa osiąga ten sam cel, aby zwrócić Optional<USB>. Zauważ, że trzecie wywołanie musi być map (), ponieważ getVersion () zwraca String zamiast opcjonalnego obiektu.

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

 23
Author: Rusty Core,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 20:22:21

Map() i flatMap()

  1. map()

Przyjmuje funkcję lambda param, gdzie T jest elementem, A R elementem zwrotnym zbudowanym za pomocą T. na końcu będziemy mieli strumień z obiektami typu R. prostym przykładem może być:

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

Po prostu pobiera elementy od 1 do 5 typu Integer, używa każdego elementu do zbudowania nowego elementu z typu String o wartości "prefix_"+integer_value i wypisuje go.

  1. flatMap()

Warto wiedzieć, że flatMap() przyjmuje funkcję F<T, R> gdzie

  • T jest typem z , z którego strumień może być zbudowany z/z. Może to być Lista (T. stream ()), tablica (Arrays.stream (someArray)), itp.. wszystko, z czego strumień może być z / lub formą. w poniższym przykładzie każdy dev ma wiele języków, więc dev. Języki są listą i będą używać parametru lambda.

  • R jest strumieniem wynikowym, który zostanie zbudowany za pomocą T. wiedząc, że mamy wiele instancji T, możemy naturalnie będzie mieć wiele strumieni z R. wszystkie te strumienie z typu R będą teraz zostaną połączone w jeden pojedynczy "płaski" strumień z Typu R.

Przykład

Przykłady Bachiri Taoufiq zobacz jego odpowiedź tutaj są proste i łatwe do zrozumienia. Dla jasności, powiedzmy, że mamy zespół programistów: {]}
dev_team = {dev_1,dev_2,dev_3}
Każdy programista zna wiele języków:]}
dev_1 = {lang_a,lang_b,lang_c},
dev_2 = {lang_d},
dev_2 = {lang_e,lang_f}

Zastosowanie Strumienia.map () on dev_team, aby uzyskać języki każdego dev:

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

Da ci taką strukturę:

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

Który jest w zasadzie List<List<Languages>> /Object[Languages[]]. Nie tak bardzo ładna, ani Java8-jak!!

Z {[16] } można "spłaścić" rzeczy, jak to ma powyższą strukturę
i zamienia go w {lang_a, lang_b, lang_c, lang_d, lang_e, lang_f}, który w zasadzie może być używany jako List<Languages>/Language[]/etc...

Więc w końcu, twój kod będzie miał więcej sensu w ten sposób:

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();

Lub po prostu:

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

Kiedy używać map () i używać flatMap():

  • Użyj map(), gdy każdy element typu T z Twojego strumienia ma zostać zmapowany/przekształcony do pojedynczego elementu typu R. wynikiem jest mapowanie typu (1 element początkowy -> 1 element końcowy) i zwracany jest nowy strumień elementów typu R.

  • Użyj flatMap(), gdy każdy element typu T z Twojego strumienia ma zmapować/przekształcić do kolekcji elementów typu R. wynikiem jest mapowanie typu (1 element startowy -> n elementy końcowe). Zbiory te są następnie scalane (lub spłaszczone ) do nowego strumienia elementów typu R. Jest to przydatne na przykład do reprezentowania zagnieżdżonych pętli .

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-26 11:59:35

Nie jestem pewien, czy powinienem na to odpowiedzieć, ale za każdym razem, gdy spotykam się z kimś, kto tego nie rozumie, używam tego samego przykładu.

Wyobraź sobie, że masz jabłko. A {[0] } to przekształcenie jabłka do apple-juice na przykład lub odwzorowanie jeden do jednego .

Weź to samo jabłko i uzyskaj z niego tylko nasiona, To właśnie robi flatMap, lub jeden do wielu, jedno jabłko jako wejście, wiele nasion jako wyjście.

 18
Author: Eugene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-09 21:03:54

Mapa:- Metoda ta przyjmuje jedną funkcję jako argument i zwraca nowy strumień składający się z wyników generowanych przez zastosowanie przekazanej funkcji do wszystkich elementów strumienia.

Wyobraźmy sobie, że mam listę wartości całkowitych (1,2,3,4,5 ) i jeden interfejs funkcji, którego logika jest kwadratowa przekazanej liczby całkowitej. (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);

Wyjście: -

[1, 4, 9, 16, 25]

Jak widać, wyjście jest nowym strumieniem, którego wartości są kwadratem wartości wejścia strumień.

[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/

FlatMap :- Ta metoda przyjmuje jedną funkcję jako argument, ta funkcja przyjmuje jeden parametr T jako argument wejściowy i zwraca jeden strumień parametru R jako wartość zwracaną. Gdy ta funkcja jest stosowana do każdego elementu tego strumienia, wytwarza strumień nowych wartości. Wszystkie elementy tych nowych strumieni generowanych przez każdy element są następnie kopiowane do nowego strumienia, który będzie wartością zwracaną tej metody.

Wyobraźmy sobie, mam listę obiektów studenckich, gdzie każdy uczeń może wybrać wiele przedmiotów.

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);

Wyjście: -

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

Jak widać, wyjście jest nowym strumieniem, którego wartości są zbiorem wszystkich elementów strumieni zwracanych przez każdy element strumienia wejściowego.

[S1 , S2, S3] - > [ {"historia", "matematyka"," geografia"}, {"ekonomia", "Biologia"}, {"Nauka"," Matematyka"} ] - > podejmuj unikalne tematy -> [Ekonomia, biologia, geografia, nauka, historia, matematyka]

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

 13
Author: lalitbhagtani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-27 14:51:17

Jeśli myślisz, że map() jest iteracją (jeden poziom pętli for), flatmap() jest iteracją dwupoziomową (jak zagnieżdżona pętla for). (Wprowadź każdy iteracyjny element foo, i wykonaj foo.getBarList() i iteruj w tym barList ponownie)


map(): weź strumień, zrób coś z każdym elementem, Zbierz pojedynczy wynik każdego procesu, wypuść inny strumień. Definicja "do something function" jest niejawna. Jeśli proces dowolnego elementu powoduje null, null służy do komponowania strumienia końcowego. Tak więc liczba elementów w strumieniu wynikowym będzie równa liczbie strumienia wejściowego.

flatmap(): pobieramy strumień elementów / strumieni i funkcję (definicja Jawna), stosujemy funkcję do każdego elementu każdego strumienia i zbieramy cały pośredni strumień wynikowy, aby był większym strumieniem("spłaszczenie"). Jeśli proces dowolnego elementu spowoduje null, pusty strumień jest dostarczany do ostatniego etapu "spłaszczania". Liczba elementów w powstałym strumieniu, jest suma wszystkich uczestniczących elementów we wszystkich wejściach, jeżeli wejściami jest kilka strumieni.

 3
Author: WesternGun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 13:07:32

Prosta odpowiedź.

Operacja map może wytworzyć Stream Stream.EX Stream<Stream<Integer>>

flatMap operacja wytworzy tylko Stream czegoś. EX Stream<Integer>

 2
Author: Melad Basilius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-15 14:44:09

Również dobra analogia może być z C#, jeśli znasz. Zasadniczo C # Select podobne do java map i C # SelectMany java flatMap. To samo dotyczy Kotlina dla zbiorów.

 1
Author: Arsenius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-14 04:12:30

To jest bardzo mylące dla początkujących. Podstawowa różnica to map emituje jeden element dla każdego wpisu na liście i {[1] } jest w zasadzie map + flatten Operacja. Aby być bardziej zrozumiałym, użyj flatMap, gdy potrzebujesz więcej niż jednej wartości, np. gdy oczekujesz pętli, która zwróci tablice, flatMap będzie bardzo pomocny w tym przypadku.

Napisałem o tym bloga, możecie to sprawdzić tutaj .

 1
Author: Niraj Chauhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-27 07:43:23

Operacje strumieniowe flatMap i map akceptują funkcję jako wejście.

flatMap oczekuje, że funkcja zwróci nowy strumień dla każdego elementu strumienia i zwraca strumień, który łączy wszystkie elementy strumieni zwracanych przez funkcję dla każdego elementu. Innymi słowy, z flatMap, dla każdego elementu ze źródła, wiele elementów zostanie utworzonych przez funkcję. http://www.zoftino.com/java-stream-examples#flatmap-operation

map oczekuje funkcji aby zwrócić przekształconą wartość i zwraca nowy strumień zawierający przekształcone elementy. Innymi słowy, z map, dla każdego elementu ze źródła, jeden przekształcony element zostanie utworzony przez funkcję. http://www.zoftino.com/java-stream-examples#map-operation

 1
Author: Arnav Rao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-27 13:09:28

flatMap() korzysta również z częściowej leniwej oceny strumieni. Odczyta strumień pięści i tylko wtedy, gdy jest to wymagane, przejdzie do następnego strumienia. Zachowanie zostało szczegółowo wyjaśnione tutaj: czy flatmap jest gwarancją lenistwa?

 0
Author: S.K.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-24 17:36:11