1. Общ преглед
API (map) и flatMap () произлизат от функционални езици. В Java 8 можете да ги намерите в Optional, Stream и CompletableFuture (макар и с малко по-различно име).
Потоците представляват последователност от обекти, докато опционалните са класове, които представляват стойност, която може да присъства или отсъства. Сред другите съвкупни операции имаме методите map () и flatMap () .
Въпреки факта, че и двете имат едни и същи видове връщане , те са доста различни. Нека да обясним тези разлики, като анализираме някои примери за потоци и опции.
2. Карта и Flatmap в Optionals
Методът map () работи добре с по избор - ако функцията връща точния тип, от който се нуждаем:
Optional s = Optional.of("test"); assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));
Въпреки това, в по-сложни случаи може да ни бъде дадена функция, която също връща опция . В такива случаи използването на map () би довело до вложена структура, тъй като изпълнението на map () прави допълнително опаковане вътрешно.
Нека да видим друг пример, за да разберем по-добре тази ситуация:
assertEquals(Optional.of(Optional.of("STRING")), Optional .of("string") .map(s -> Optional.of("STRING")));
Както виждаме, в крайна сметка получаваме вложената структура по избор
Точно това ни помага flatMap () :
assertEquals(Optional.of("STRING"), Optional .of("string") .flatMap(s -> Optional.of("STRING")));
3. Карта и Flatmap в потоци
И двата метода работят по подобен начин по избор .
Методът map () обгръща основната последователност в екземпляр на Stream , докато методът flatMap () позволява да се избегне вложен Stream
В следващия пример map () създава поток, състоящ се от резултатите от прилагането на метода toUpperCase () към елементите на входния поток:
List myList = Stream.of("a", "b") .map(String::toUpperCase) .collect(Collectors.toList()); assertEquals(asList("A", "B"), myList);
map () работи доста добре в такъв прост случай, но какво ще стане, ако имаме нещо по-сложно, като списък със списъци като вход.
Нека да видим как работи:
List
list = Arrays.asList( Arrays.asList("a"), Arrays.asList("b")); System.out.println(list);
Този фрагмент отпечатва списък със списъци [[a], [b]].
Сега, нека използваме flatMap () :
System.out.println(list .stream() .flatMap(Collection::stream) .collect(Collectors.toList()));
Резултатът от такъв фрагмент ще бъде изравнен до [a, b].
T той flatMap () метод първо се изравнява входния поток от предавания на живо на Strings (за повече за изправяне, вижте статията). След това работи подобно на метода map () .
4. Заключение
Java 8 ни дава възможност да използваме методите map () и flatMap () , които първоначално са били използвани във функционални езици.
Можем да ги извикаме в Streams и Optionals. Тези методи ни помагат да получаваме картографирани обекти, като прилагаме предоставената функция за картографиране.
Както винаги, можете да разгледате примерите, предоставени в тази статия, в GitHub.