Как преобразовать Stream в Map в Java?

«Как преобразовать Stream в Map в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для преобразования Stream в Map используются коллекторы Collectors.toMap() и Collectors.groupingBy().

1. Collectors.toMap() — для создания мапы из пар ключ-значение.

List<String> fruits = List.of("apple", "banana", "cherry");
// Простое преобразование: элемент -> ключ, его длина -> значение
Map<String, Integer> fruitLengthMap = fruits.stream()
    .collect(Collectors.toMap(
        fruit -> fruit,          // Функция для ключа
        String::length           // Функция для значения
    ));
// Результат: {apple=5, banana=6, cherry=6}

2. Обработка дубликатов ключей (обязательна, если возможны коллизии):

List<String> fruitsWithDuplicates = List.of("apple", "apricot", "banana");
Map<Character, String> firstLetterMap = fruitsWithDuplicates.stream()
    .collect(Collectors.toMap(
        s -> s.charAt(0),        // Ключ — первая буква
        s -> s,                  // Значение — строка
        (existing, replacement) -> existing + ", " + replacement // Функция слияния
    ));
// Результат: {a=apple, apricot, b=banana}

3. Collectors.groupingBy() — для группировки элементов по ключу.

Map<Character, List<String>> groupedByFirstLetter = fruits.stream()
    .collect(Collectors.groupingBy(s -> s.charAt(0)));
// Результат: {a=[apple, apricot], b=[banana], c=[cherry]}

4. Специфичная мапа (например, TreeMap):

Map<String, Integer> sortedMap = fruits.stream()
    .collect(Collectors.toMap(
        Function.identity(),
        String::length,
        (v1, v2) -> v1,
        TreeMap::new            // Поставщик конкретной реализации Map
    ));