Как преобразовать Map в List в Java? Нужны все значения, ключи или пары ключ-значение
Преобразование Map в List: три основных подхода
Проблема в том, что Map.values() возвращает Collection<V>, а не List<V>. В Java нельзя просто привести Collection к List — это разные интерфейсы. Нужно явно создать новый список. Рассмотрим все три варианта, которые вам нужны.
1. Получить список ключей (Set → List)
Самый простой случай. Ключи в Map уникальны, поэтому keySet() возвращает Set<K>. Преобразуем его в ArrayList через конструктор:
Map<String, String> books = new HashMap<>();
books.put("978-5-699-12014-7", "Война и мир");
books.put("978-5-17-089834-0", "Преступление и наказание");
books.put("978-5-04-091034-4", "Мастер и Маргарита");
// Способ 1: через конструктор ArrayList
List<String> isbnList = new ArrayList<>(books.keySet());
System.out.println(isbnList); // [978-5-04-091034-4, 978-5-17-089834-0, 978-5-699-12014-7]
2. Получить список значений (Collection → List)
Аналогично, но используем values():
// Способ 1: через конструктор ArrayList
List<String> titles = new ArrayList<>(books.values());
System.out.println(titles); // [Мастер и Маргарита, Преступление и наказание, Война и мир]
// Способ 2: через Stream API (Java 8+)
List<String> titlesStream = books.values().stream()
.collect(Collectors.toList());
System.out.println(titlesStream); // тот же результат
3. Получить список пар "ключ-значение"
Здесь сложнее. Нужно преобразовать каждую запись Map.Entry в объект, который будет содержать и ключ, и значение. Чаще всего используют:
- Список строк (например, "ISBN: Название")
- Список кастомных объектов (например, класс Book)
Пример со строками:
List<String> entries = new ArrayList<>();
for (Map.Entry<String, String> entry : books.entrySet()) {
entries.add(entry.getKey() + " -> " + entry.getValue());
}
System.out.println(entries);
// [978-5-04-091034-4 -> Мастер и Маргарита, 978-5-17-089834-0 -> Преступление и наказание, 978-5-699-12014-7 -> Война и мир]
Пример с кастомным классом (более правильный подход для сложных приложений):
class Book {
String isbn;
String title;
Book(String isbn, String title) {
this.isbn = isbn;
this.title = title;
}
@Override
public String toString() {
return isbn + " -> " + title;
}
}
// Преобразование
List<Book> bookList = books.entrySet().stream()
.map(entry -> new Book(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
System.out.println(bookList);
// [978-5-04-091034-4 -> Мастер и Маргарита, 978-5-17-089834-0 -> Преступление и наказание, 978-5-699-12014-7 -> Война и мир]
Важные замечания
- Порядок элементов: если используете
HashMap, порядок не гарантирован. Для сохранения порядка вставки используйтеLinkedHashMap. - Производительность: конструктор
new ArrayList<>(collection)работает за O(n). Для больших Map это нормально. - Stream API (Java 8+) — более функциональный стиль, но для простых случаев конструктор быстрее и читаемее.
- Изменяемость: полученный список можно модифицировать (добавлять/удалять элементы). Если нужен неизменяемый список, используйте
List.copyOf()(Java 10+) илиCollections.unmodifiableList().
Выберите подход под свою задачу. Для простого извлечения значений — конструктор ArrayList. Для сложных преобразований — Stream API с кастомными объектами.
<<Краткий альтернативный ответ: используйте List.copyOf() и утилитарные методы
Если вам не нужно изменять полученный список (он будет только для чтения), можно использовать методы Java 10+:
// Неизменяемый список ключей
List<String> isbnList = List.copyOf(books.keySet());
// Неизменяемый список значений
List<String> titles = List.copyOf(books.values());
// Неизменяемый список пар (через Stream)
List<String> entries = books.entrySet().stream()
.map(e -> e.getKey() + " -> " + e.getValue())
.collect(Collectors.toUnmodifiableList());
Плюсы: кратко, безопасно (список нельзя случайно изменить), иммутабельность улучшает потокобезопасность. Минусы: если попытаетесь добавить элемент, получите UnsupportedOperationException.
Ещё один лайфхак: если вам нужно отсортировать результат, добавьте .sorted() в Stream:
List<String> sortedTitles = books.values().stream()
.sorted()
.collect(Collectors.toList());
Для большинства простых задач этого достаточно. Главное — помнить, что Map.values() — это Collection, а не List, и его нужно явно преобразовывать.
Ответов пока нет.
Войдите чтобы оставить ответ