Как преобразовать Stream в Map с помощью метода collect в Java?

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

Ответ

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

Базовый пример с toMap:

List<String> words = Arrays.asList("apple", "banana", "cherry");

// keyMapper: элемент -> ключ, valueMapper: элемент -> значение
Map<String, Integer> wordToLength = words.stream()
    .collect(Collectors.toMap(
        word -> word,           // Ключ - сама строка
        word -> word.length()   // Значение - длина строки
    ));
// Результат: {apple=5, banana=6, cherry=6}

Важные нюансы:

  1. Уникальность ключей: Если ключи дублируются, будет выброшено IllegalStateException. Решение — добавить merge function:

    // При конфликте берется первое значение
    Collectors.toMap(key -> key, value -> value, (first, second) -> first)
  2. Конкретная реализация Map: Можно указать поставщик:

    Collectors.toMap(..., TreeMap::new) // Получим TreeMap вместо HashMap
  3. Группировка элементов с одинаковым ключом (groupingBy):

    // Группировка слов по длине
    Map<Integer, List<String>> wordsByLength = words.stream()
    .collect(Collectors.groupingBy(String::length));
    // Результат: {5=[apple], 6=[banana, cherry]}

Почему toMap? Это декларативный и потокобезопасный способ преобразования данных, интегрированный в Stream API.