Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как превратить список в Map

Короткий ответ

Collectors.toMap() принимает две функции: как получить ключ и как получить значение:

record User(int id, String name) {}
 
void main() {
    var users = List.of(new User(1, "Anna"), new User(2, "Oleg"));
 
    Map<Integer, String> names = users.stream().collect(Collectors.toMap(User::id, User::name));
    IO.println(names.get(2));
}

Результат:

Oleg

Объект целиком как значение

Function.identity() возвращает сам элемент — так строят индекс по ключу:

record User(int id, String name) {}
 
void main() {
    var users = List.of(new User(1, "Anna"), new User(2, "Oleg"));
 
    Map<Integer, User> byId = users.stream().collect(Collectors.toMap(User::id, Function.identity()));
    IO.println(byId.get(1));
}

Результат:

User[id=1, name=Anna]

Повторяющиеся ключи и порядок

Третий аргумент решает, какое значение оставить при совпадении ключей, а четвёртый задаёт тип Map:

void main() {
    var words = List.of("apple", "avocado", "banana", "blueberry", "cherry");
 
    var longestByLetter = words.stream().collect(Collectors.toMap(
            w -> w.charAt(0),
            w -> w,
            (a, b) -> a.length() >= b.length() ? a : b,
            LinkedHashMap::new));
    IO.println(longestByLetter);
}

Результат:

{a=avocado, b=blueberry, c=cherry}

Частая ошибка

Не учесть повторяющиеся ключи. Без функции слияния toMap() выбрасывает исключение:

void main() {
    var words = List.of("apple", "avocado");
    words.stream().collect(Collectors.toMap(w -> w.charAt(0), w -> w));
}

Результат:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key a (attempted merging values apple and avocado)

Ещё одна ловушка: toMap() не принимает null в качестве значения и выбрасывает NullPointerException.

Функции из этого ответа

  • Collectors.toMap() — Сборщик, который строит словарь из элементов потока.
  • Function — Функция, которая принимает значение типа `T` и возвращает значение типа `R`.
  • Collectors.groupingBy() — Сборщик, который раскладывает элементы по группам с общим ключом.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.