Razlika između karte () i flatMap ()

1. Pregled

karta() i flatMap () API-ji proizlaze iz funkcionalnih jezika. U Javi 8 možete ih pronaći u Neobvezno, Stream i u CompletableFuture (iako pod nešto drugačijim imenom).

Potoci predstavljaju slijed objekata, dok su opcionalne klase koje predstavljaju vrijednost koja može biti prisutna ili odsutna. Među ostalim skupnim operacijama imamo i karta() i flatMap () metode.

Unatoč činjenici da obje imaju iste vrste povrata, sasvim su različiti. Objasnimo ove razlike analizirajući neke primjere tokova i opcija.

2. Karta i plosna karta u opcijama

The karta() metoda dobro funkcionira s Neobvezno - ako funkcija vrati točan tip koji nam treba:

Neobvezno s = Neobvezno.of ("test"); assertEquals (Neobvezno.of ("TEST"), s.map (String :: toUpperCase));

Međutim, u složenijim slučajevima mogli bismo dobiti funkciju koja vraća Neobvezno isto. U takvim slučajevima koristeći karta() dovelo bi do ugniježđene strukture, kao karta() implementacija interno dodatno umotava.

Pogledajmo još jedan primjer kako bismo bolje razumjeli ovu situaciju:

assertEquals (Neobavezno.of (Neobavezno.of ("STRING")), Neobavezno .of ("niz") .map (s -> Neobavezno.of ("STRING")));

Kao što vidimo, na kraju imamo ugniježđenu strukturu Neobvezno. Iako djeluje, prilično je nezgodno za upotrebu i ne pruža nikakvu dodatnu nulu sigurnost, pa je bolje zadržati ravnu strukturu.

Upravo to flatMap () pomaže nam učiniti:

assertEquals (Izborno.of ("STRING"), Izborno .of ("niz") .flatMap (s -> Izborno.of ("STRING")));

3. Karta i ravan prikaz u streamovima

Obje metode rade slično za Neobvezno.

The karta() metoda obavija temeljni slijed u Stream primjerice, dok flatMap () metoda omogućuje izbjegavanje ugniježđenih Stream struktura.

U sljedećem primjeru, karta() proizvodi a Stream koji se sastoji od rezultata primjene toUpperCase () metoda na elemente unosa Prijenos:

Popis myList = Stream.of ("a", "b") .map (String :: toUpperCase) .collect (Collectors.toList ()); assertEquals (asList ("A", "B"), myList);

karta() djeluje prilično dobro u tako jednostavnom slučaju, ali što ako imamo nešto složenije, poput popisa popisa kao ulaz.

Pogledajmo kako to funkcionira:

Popis list = Arrays.asList (Arrays.asList ("a"), Arrays.asList ("b")); System.out.println (popis);

Ovaj isječak ispisuje popis popisa [[a], [b]].

A sada, upotrijebimo a flatMap ():

System.out.println (list .stream () .flatMap (Collection :: stream) .collect (Collectors.toList ()));

Rezultat takvog isječka bit će izravnan [a, b].

Ton flatMap () metoda prvo izravnava ulaz Stream od Potoci do a Stream od Žice (više o izravnavanju pogledajte u članku). Nakon toga djeluje slično kao karta() metoda.

4. Zaključak

Java 8 daje nam mogućnost korištenja karta() i flatMap () metode koje su se izvorno koristile u funkcionalnim jezicima.

Na njih se možemo pozvati Potoci i Opcionalne. Ove metode pomažu nam u dobivanju mapiranih objekata primjenom pružene funkcije mapiranja.

Kao i uvijek, primjere iz ovog članka možete pogledati na GitHubu.