Будь ласка, перейдіть до публікації повністю, щоб отримати чітке уявлення,
карта проти flatMap:
Щоб повернути довжину кожного слова зі списку, ми зробимо щось подібне нижче.
Коротка версія наведена нижче
Коли ми збираємо два списки, наведені нижче
Без плоскої карти => [1,2], [1,1] => [[1,2], [1,1]] Тут два списки розміщені всередині списку, тож вихід буде списком, що містить списки
З плоскою картою => [1,2], [1,1] => [1,2,1,1] Тут два списки згладжені і лише значення розміщені в списку, тому вихід буде списком, що містить лише елементи
В основному він об'єднує всі об'єкти в один
## Детальна версія надана нижче: -
Наприклад: -
Розгляньте список [“STACK”, “OOOVVVER”], і ми намагаємось повернути такий список, як [“STACKOVER”] (повертаючи з цього списку лише унікальні літери). Спочатку ми зробимо щось подібне нижче, щоб повернути список [“STACKOVER”] від [“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());
}
}
Тут проблема полягає в тому, що Ламбда, переданий методу map, повертає масив String для кожного слова. Отже, потік, повернутий методом map, насправді має тип Stream, але нам потрібен Stream для представлення потоку символів, нижче зображення зображено проблема.
Малюнок A:
Ви можете подумати, що ми можемо вирішити цю проблему за допомогою плоскої карти.
Добре, давайте подивимося, як вирішити це за допомогою map та Arrays.stream
Перш за все вам знадобиться потік символів замість потоку масивів. Існує метод під назвою Arrays.stream (), який би взяв масив і виробляє потік, наприклад:
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());
Наведене досі не працює, тому що ми закінчуємо список потоків (точніше, Stream>), натомість ми повинні спершу перетворити кожне слово в масив окремих літер, а потім зробити кожен масив окремим потоком
Використовуючи flatMap, ми повинні мати можливість виправити цю проблему, як показано нижче:
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 буде виконувати відображення кожного масиву не з потоком, а з вмістом цього потоку. Усі окремі потоки, які будуть генеровані під час використання карти (масиви :: потік), об'єднуються в один потік. На малюнку B показано ефект використання методу flatMap. Порівняйте його з картою, яку робить на малюнку А.
Малюнок B
Метод flatMap дозволяє замінити кожне значення потоку на інший потік, а потім об'єднає всі створені потоки в один потік.
map :: Stream T -> (T -> R) -> Stream R
,flatMap :: Stream T -> (T -> Stream R) -> Stream R
.