Пожалуйста, пройдите по почте полностью, чтобы получить ясное представление,
карта против плоской карты:
Чтобы вернуть длину каждого слова из списка, мы сделаем что-то вроде ниже.
Короткая версия приведена ниже
Когда мы собираем два списка, приведенных ниже
Без плоской карты => [1,2], [1,1] => [[1,2], [1,1]] Здесь два списка размещены внутри списка, поэтому на выходе будет список, содержащий списки
С плоской картой => [1,2], [1,1] => [1,2,1,1] Здесь два списка сглаживаются и в список помещаются только значения, поэтому на выходе будет список, содержащий только элементы
В основном это объединяет все объекты в один
## Подробная версия была дана ниже: -
Например: -
Рассмотрим список [«STACK», «OOOVVVER»], и мы пытаемся вернуть список наподобие [«STACKOVER»] (возвращая только уникальные буквы из этого списка). Сначала мы бы сделали что-то подобное ниже, чтобы вернуть список [«STACKOVER»] из [«STACK», «ОООВВВЕР»]
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());
}
}
Здесь проблема в том, что лямбда, переданная методу карты, возвращает массив String для каждого слова, поэтому поток, возвращаемый методом карты, на самом деле имеет тип Stream, но нам нужен Stream для представления потока символов, ниже изображение иллюстрирует проблема.
Рисунок А:
Вы можете подумать, что мы можем решить эту проблему, используя flatmap,
хорошо, давайте посмотрим, как решить эту проблему, используя 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 будет выполнять сопоставление каждого массива не с потоком, а с содержимым этого потока. Все отдельные потоки, которые генерируются при использовании map (Arrays :: stream), объединяются в один поток. На рисунке B показан эффект использования метода flatMap. Сравните это с тем, что делает карта на рисунке A.
Рисунок B
Метод flatMap позволяет заменить каждое значение потока другим потоком, а затем объединяет все созданные потоки в один поток.
map :: Stream T -> (T -> R) -> Stream R
,flatMap :: Stream T -> (T -> Stream R) -> Stream R
.