Оптимальное преобразование списка в Map в Java
Быстрый ответ
Вы можете превратить List
в Map
, воспользовавшись возможностями Stream API и методом Collectors.toMap()
. Для этого следует определить, какой атрибут вашего объекта будет служить ключом, а сам объект — значением в Map
:
List<YourObject> list = // ...;
Map<PropertyType, YourObject> map = list.stream()
.collect(Collectors.toMap(YourObject::getProperty, Function.identity()));
Здесь YourObject::getProperty
— это функция, которая возвращает ключ, а Function.identity()
позволяет использовать сам объект в качестве значения. Если вы столкнулись с дубликатами ключей, воспользуйтесь третьим параметром — функцией слияния:
Map<PropertyType, YourObject> map = list.stream()
.collect(Collectors.toMap(YourObject::getProperty, Function.identity(), (first, second) -> first));
Профессиональное управление дубликатами
Если ваш список содержит одинаковые ключи, вам следует аккуратно объединить их. Например, если у вас два списка значений для одного и того же ключа, их можно объединить с помощью функции слияния:
Map<PropertyType, Integer> map = list.stream()
.collect(Collectors.toMap(YourObject::getKey, YourObject::getValue, Integer::sum));
Таким образом, значения для совпадающих ключей будут суммироваться.
Уделите внимание выбору карты
Выбирать реализацию Map
стоит исходя из подобающей задачи: HashMap
, TreeMap
, LinkedHashMap
— каждая из них имеет свои нюансы.
Map<PropertyType, YourObject> linkedHashMap = list.stream()
.collect(Collectors.toMap(YourObject::getProperty, Function.identity(),
(existing, replacement) -> existing, LinkedHashMap::new));
Скорость имеет значение
Если ваша задача требует высокой производительности, инициализируйте HashMap
с параметром начальной емкости, равным размеру List
.
Есть и альтернативы
Библиотека Google Guava предлагает метод Maps.uniqueIndex()
для упращенного преобразования списка в карту:
ImmutableMap<PropertyType, YourObject> map = Maps.uniqueIndex(list, YourObject::getProperty);
Визуализация
Можно преобразовать список объектов в четкую структуру с ипользованием карты:
ID книги | Место на полке (Книга) |
---|---|
1 | 📗 |
2 | 📘 |
3 | 📙 |
Теперь книги организованы понятно и доступны для быстрого поиска.
Map<ID, Book>: {
1 -> 📗,
2 -> 📘,
3 -> 📙
}
Сложности? Облегчите их!
Сложные задачи могут быть упрощены с помощью пользовательских лямбда-выражений:
Map<String, Integer> personMap = persons.stream()
.collect(Collectors.toMap(
p -> p.getName() + " " + p.getSurname(),
Person::getAge,
(age1, age2) -> age1
));
Преобразовывать в карту или нет?
Выбор между типами коллекций зависит от ваших задач и требований к количеству используемой памяти — карта идеально подходит для быстрого доступа, но требует более обширного пространства памяти.
Возвращение в школу (документация)
Не забывайте обращаться к документации Java для глубокого понимания методов коллекций и работы со Stream API.
Полезные материалы
- Collectors (Java Platform SE 8 ) — детальная информация о коллекторах.
- java – Разделение списка на подсписки — информация об операции разбиения списков.
- Java 8 Streams – Примеры использования Collectors.toMap() — руководство по использованию
Collectors.toMap()
. - GitHub Gist Пример преобразования списка в карту — пример преобразования списка в карту.